Teofrostus
Teofrostus

Reputation: 1596

What is the scope of variables and methods included via ruby modules?

Suppose I have the following:

module MyModule
  module SubModule
    Var = 'this is a constant'
    var = 'this is not a constant'
    def hello_world
      return 'hello world!'
    end
  end
end

In the same file, I can only seem to access MyModule::SubModule::Var, but not any the constant or the method. If I now create a class and include these modules in different ways, I get additional strange behavior:

class MyClass
  include MyModule
  def initialize()
    puts SubModule::Var
  end

  def self.cool_method
    puts SubModule::Var
  end
end

In this case, I can again only access Var, but not the other two. SubModule::var and SubModule::hello_world do not work. Finally:

class MyClass
  include MyModule::SubModule
  def initialize()
    puts Var
    puts hello_world
  end
  def self.cool_method
    puts Var
    puts hello_world
  end
end

In this case, I can now access both Var and the method hello_world but not var, and, the weirdest thing, is that hello_world appears to have become an instance method! That is, the call to hello_world in initialize works, but the one in self.cool_method doesn't. This is pretty strange, considering that Var seems to have been included as a class variable, since outside the class, I must access them like so:

MyClass::Var
x = MyClass.new
x.hello_world

So, I have a few major questions.

  1. What is going on behind the scenes with regards to Var vs var? It appears that capitalizing a variable name is more than just a convention after all.
  2. When includeing a module, what kinds of things are passed to the including class, and at what scope?
  3. Is there a way to do the opposite? That is, use include to include an instance variable or a class method?

Upvotes: 0

Views: 772

Answers (1)

Jörg W Mittag
Jörg W Mittag

Reputation: 369428

What is going on behind the scenes with regards to Var vs var? It appears that capitalizing a variable name is more than just a convention after all.

Yes, of course, it's not a convention. Variables which start with an uppercase letter are constants, variables which start with a lowercase letter are local variables. The two are completely different.

When includeing a module, what kinds of things are passed to the including class, and at what scope?

Nothing gets passed anywhere. includeing a mixin simply makes that mixin the superclass of the class you are includeing it into. That's all. Everything else then works exactly as with classes.

Is there a way to do the opposite? That is, use include to include an instance variable or a class method?

I don't understand this question. Instance variables have nothing to do with mixins or classes. They belong to instances, that's why they are called "instance" variables.

There are no such things as "class methods" in Ruby. Ruby only knows one kind of methods: instance methods. When Rubyists talk to each other, they will sometimes use the term "class method" to mean "singleton method of an object that happens to be a class", but they do that knowing full well that class methods don't actually exist, it's just a shorthand in conversation. (And, of course, singleton methods don't exist either, they are just a convenient way of saying "instance method of the singleton class".)

Upvotes: 3

Related Questions