rubyrubygemsapiblueprint

How do I use another gem as a dependency and create a class that inherits from it


I'm trying to create a gem, that wraps some external API calls, and I want to use a gem called 'api-blueprint'

I already added as a dependency on my gemspec file spec.add_runtime_dependency 'api-blueprint'.

and now I want some of my classes to inherit from it

module MyGem
  class Request < ApiBlueprint::Model
    ... code ...
  end
end

And I get an error

NameError:
  uninitialized constant MyGem::ApiBlueprint

And I'm not sure how can I inherit from a dependency without appending my gem name to the namespace. I also tried without wrapping it inside a module, but I get the same issue, albeit without MyGem namespace.

I used this gem inside a rails app, with the same use without problems, but now I need to refactor that logic out of the rails app into a gem.

I also tried to require both as api_blueprint and api-blueprint the latter returning this error

Failure/Error: require "api-blueprint"

ArgumentError:
  wrong number of arguments (given 2, expected 0)

and the former just returning a LoadError. I'm not sure what seems to be the issue here, do I need to include elsewhere besides the gemspec file? Note that I also use spec.add_dependency but I got the same issues. I'm a bit lost here, this is my first go at a rubygem

Thanks for the attention :)


Solution

  • And I'm not sure how can I inherit from a dependency without appending my gem name to the namespace.

    You don't need to do that. You're just being confused by a misleading error message.

    In ruby, constant lookups are first attempted inside the module and then in the global namespace.

    So in other words, this code:

    module MyGem
      class Request < ApiBlueprint::Model
    

    is first trying to find the constant: MyGem::ApiBlueprint::Model, and (if that fails), it then tries to find the constant: ApiBlueprint::Model. If that fails too, it uses the first error message, which is what you're seeing.

    To prevent the confusing error message (although this alone won't fix the actual problem!!), you can explicitly tell the interpreter to only look for the constant in the global namespace:

    module MyGem
      class Request < ::ApiBlueprint::Model
    

    Failure/Error: require "api-blueprint"
    
    ArgumentError:
      wrong number of arguments (given 2, expected 0)
    

    You'll need to give us more context on that error. What's the stack trace? What method is being called with 2 arguments instead of 0?

    As far as I can tell, adding this require statement should be all you need to do.