user8058357
user8058357

Reputation:

How to load a file into a class scope

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

Answers (2)

steenuil
steenuil

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

Jörg W Mittag
Jörg W Mittag

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 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.

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 "requireing a file into a class's scope).

Upvotes: 3

Related Questions