Why does Ruby not allow access to a method from a class unless prefixed with the module name

module Hello
  def self.log()
    p "log called"
  end

  class Shape
    def self.test
      log
    end
  end

  def self.test1
    log
  end

end

Hello::Shape.test # undefined local variable or method `log'
Hello.test1 # prints "log called"

      

I know the first statement will work if I prefix log with Hello like: Hello.log

But why can't Shape access the log method even though it's in the same module?

+3


source to share


2 answers


Whenever you enter a method call without an explicit receiver like

log

      

Same as

self.log

      

So you basically do



class Shape
  def self.test
    self.log
  end
end

      

self

Shape

and Shape

has no method log

. This is why you are getting the error. To do what you want to do, you need to add a method Hello

to Shape

. But this is impossible ! def self.log

adds a method to the Hello

singleton class, and when it comes to singleton methods, Ruby really doesn't let you move them around. Singleton methods only work on one instance.

So how can you get around this? The key is to define log

as a normal instance method - then you can easily move it to other classes and modules.

module Hello
  # add all instance methods as class methods
  extend self

  def log
    p "log called"
  end

  class Shape
    # Module.nesting.last is just a clever way of referring to Hello
    extend Module.nesting.last

    def self.test
      log
    end
  end

  def test1
    log
  end
end

      

+2


source


Since self is Shape, Ruby will by default look for the log method defined in the Shape class. You don't have a log method, so it throws an error. Even if Shape is in the same module, when you use the "class" keyword, Ruby opens a new context, which means that all definitions of methods, variables, etc. defined in the Hello module go outside the scope of the Shape class. You must explain which log method you want to call by prefixing it with the class or module name in the Shape class.



0


source







All Articles