Reputation: 17900
I have the following module defined, together with a module method and a method nested inside the module's method:
module RansackHelpers
def self.split(attribute, model_class)
def run(memo, model_class, attribute)
# Code
end
run([], model_class, attribute)
end
end
How can I call run
inside self.split
? Apparently, it doesn't found the nested method.
Upvotes: 0
Views: 528
Reputation: 230286
If you wanted to have a "local function", you can emulate it with lambdas.
module RansackHelpers
def self.split(attribute, model_class)
run = ->(memo, model_class, attribute) do
# Code
end
run.call([], model_class, attribute)
end
end
From this example, it's not obvious why you'd want to do this. If it's defined and called right away, you might as well just execute the function body directly. If it's to be used from outside, you should create a normal, not nested method.
For recursive calls, this should be just the thing.
Upvotes: 1
Reputation: 80065
There is no such thing as a nested method in Ruby. If you call run
before split
you will get a NoMethod error. If you call split twice you will get a warning: "warning: method redefined; discarding old run."
You have a method split
which defines another method when called.
Upvotes: 1
Reputation: 6674
There is a current class conception in Ruby, according to Metaprogramming Ruby 2
Wherever you are in a Ruby program, you always have a current object:
self
. Likewise, you always have a current class (or module). As The Ruby interpreter always keeps a reference to the current class (or module), when you define a method, that method becomes an instance method of the current class.
And it changes with the class
and module
keyword.
When you open a class with the
class
keyword (or a module with themodule
keyword), that class becomes the current class.
So in your case, the current class of where run
method defined is still RansackHelpers
, but not RansackHelpers
's singleton class.
Here it works,
module RansackHelpers
class << self
def split(attribute, model_class)
def run(memo, model_class, attribute)
# Code
end
run([], model_class, attribute)
end
end
end
Upvotes: 2