Reputation: 24850
Let's say we have code looks like this
module TM
def aa
puts "aa"
end
def bb
TM::aa
end
module_function :bb
end
TM.bb
Why bb cannot access aa by no matter "TM::aa", "self.aa" or "TM.aa"? They are in the same module. What is the benefit of setting such restriction and how do I solve the "undefined method" error?
Upvotes: 0
Views: 103
Reputation: 43
I think you may be confused about the functionality of the call to module_function, as this method actually creates a copy of the method and makes the original method private, and mixes the copy into the meta-class (or eigenclass, in any case one step up on the method lookup chain). This is so it can be overridden without effecting internal use of the method, i.e. to make it safe for private use while also being publicly usable OR publicly overrideable. It's only the copy that's mixed into the meta-class that can't access aa, and that's because aa doesn't exist above it in the lookup chain. If both methods were passed into module function then you won't get the undefined method error.
Upvotes: 1
Reputation: 6827
This does not work because you are defining an instance method (def aa) instead of a module method (def self.aa).
Check out the documentation:
A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function)
So what you want might be:
module TM
def self.aa
puts "aa"
end
def bb
TM::aa
end
module_function :bb
end
TM.bb
Upvotes: 1
Reputation: 46667
Because aa
is a instance function. If you add it to the module_function
list (or use one of the many other methods of declaring module methods), everything works. Personally, I prefer:
module TM
def self.aa
puts "aa"
end
def self.bb
TM::aa
end
end
TM.bb
Upvotes: 1
Reputation: 9225
Did you mean something like this?
module TM
class << self
def aa
puts "aa"
end
def bb
TM::aa
end
end
end
TM.bb
UPDATE: methods as you defined them will be accessible as instance methods when you include
your module or class methods if you extend
your class
module TM
def aa
puts "aa"
end
def bb
aa
end
end
class A
include TM
end
class B
extend TM
end
A.new.bb
B.bb
Upvotes: 4