Reputation:
In InterfaceServer#initialize
, I intend to build a path to a file, and load the file into InterfaceServer
class's scope.
This is my code:
class InterfaceServer
def initialize(channel)
@channel_path = channel + "_implementation"
end
require_relative @channel_path
end
I get this error:
error => `require_relative': no implicit conversion of nil into String (TypeError)
Wrapping the require_relative
statement in a method would solve the problem, but it defeats my requirement for the file to be loaded into the class's scope.
The problem is associated with scope gates, but I can't make it work. I read that instance variables are accessible to all methods in the class. Why am I getting the error? Can anyone help with a solution?
Upvotes: 1
Views: 155
Reputation: 384
require_relative @channel_path
is called when Ruby loads the InterfaceServer
class, but @channel_path
is only defined later when the class is instantiated.
If you want to define which modules to load into the class at runtime, you could put the methods you want to include from the '_implementation' files in different modules, and include
each module in the class.
class InterfaceServer; end
channels.each do |channel|
InterfaceServer.include Object.const_get(channel.capitalize)
end
Upvotes: -1
Reputation: 369458
Instance variables belong to objects ("instances"), that's why they are called instance variables. You have two completely different objects here: InterfaceServer
and an instance of InterfaceServer
. They are different objects (after all, they don't even the same class! InterfaceServer
has class Class
, the instance of InterfaceServer
has class InterfaceServer
), so they have different instance variables as well.
My code requires a file to be loaded into the
InterfaceServer
class's scope. […] Wrapping therequire_relative
statement in a method would solve the problem, but it defeats my requirement for the file to be loaded into the class's scope.
require_relative
simply runs the file. It has nothing to do with scopes. Where the call to require_relative
is located is irrelevant.
(Oh, and also: require_relative
is not a statement, it is an expression. In fact, there are no statements in Ruby, everything is an expression.)
The problem is associated with scope gates
Nope, it isn't.
I read that instance variables are accessible to all methods in the class.
Instance variables belong to instances. They have nothing to do with methods.
Why am I getting the error?
The instance variable @channel_path
of InterfaceServer
has nothing to do with the instance variable @channel_path
of the instance of InterfaceServer
. Since you never assigned to the instance variable @channel_path
of InterfaceServer
, it doesn't exist, and non-existing instance variables evaluate to nil
, ergo you are calling require_relative
with nil
as an argument.
Can anyone help with a solution?
Not really, since you haven't stated the problem. What you are doing is a) impossible (there are multiple instances of the class, so which instance's @channel_path
should be used?) and b) non-sensical (there is no such thing as "require
ing a file into a class's scope).
Upvotes: 3