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 endYou have to call
superif 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
