I am new to Ruby; thus, please forgive if ask this question incorrectly
I have a class that loads a collection and loads items into a collection based on a certain criteria
require_relative 'thing'
class Someclass
def self.tings
things=load_things()
end
def self.select_things(something)
return things.select { |thing| thing.some_property == something }
end
end
I would like to use method_missing instead of the direct defintions
require_relative 'thing'
class Someclass
def self.method_missing(method, *args)
things=load_things()
if method == 'select_things'
self.send("things.select { |thing| thing.some_property == args }")
end
end
end
However, this approach doesn't work and method_missing just outputs the code string. Is there a proper way to call a code from method_missing?
Thank you very much everyone in advance
CodePudding user response:
There are two issues with your method_missing
implementation:
The method name is given as a symbol, not as a string:
def self.method_missing(method, *args) if method == :select_things # ... end end
You have to call
super
if you don't process the message yourself:def self.method_missing(method, *args) if method == :select_things # ... else super end end
If you don't call super
your object is going to swallow any message without ever raising a NoMethodError
and you'll have a very hard time understanding why your code isn't working.
In addition, you should also implement respond_to_missing?
to return true
for the messages you are responding to, e.g.:
def self.respond_to_missing?(method, include_all = false)
[:select_things].include?(method) || super
end
The above gives you:
Someclass.respond_to?(:select_things) #=> true