あなたが動物園を持っているとしましょう。たくさんの野生動物がいるとても素敵な動物園です。もちろん、動物園の飼育係として、ニーズや特性に基づいて特定の動物を見つける必要があることがよくあります。しかし、動物園がどんどん大きくなるにつれて、これらの特徴がどうなるかを前もって知ることは不可能です! これを修正してみましょう...
まず、動物とは何かを定義しましょう。
class Animal
def initialize(attributes)
@attributes = attributes
end
def [](value)
@attributes[value]
end
end
簡単です。さぁ、動物園を作ろう!
class Zoo
def animals
@animals ||= []
end
end
動物がいない動物園とは?
zoo = Zoo.new
zoo.animals << Animal.new(type: "Mighty Giraffe", legs: 4, region: 'Africa')
zoo.animals << Animal.new(type: "Fierce Pidgin", legs: 2, region: 'America')
zoo.animals << Animal.new(type: "Wild Boar", legs: 4, region: 'Africa')
完全。私たちは今、動物でいっぱいの動物園を持っています。今では、それぞれに特徴があることはわかっていますが、まだ見つけることができていません.
zoo.find_animals_by_region('Africa')
しかし、覚えておいてください、私たちはこれらすべての特徴を前もって知りません! 動物園に特別なメソッドを追加して、これを修正してみましょう。
class Zoo
def animals
@@animals ||= []
end
def method_missing(method_name, *args, &block)
# stuff here
end
end
これで、Zoo の未定義メソッドへのすべての呼び出しをキャッチできるようになりました。つまり、find_animals_by_something は未定義であるため、すぐにキャッチされます。さらに、使用された method_name も取得します。すごい!これを有効に活用しましょう。
class Zoo
def animals
@@animals ||= []
end
def method_missing(method_name, *args, &block)
if method_name.to_s.start_with?('find_animals_by_')
# here we go!
end
end
end
どうぞ!特別なキーワード「find_animals_by_」で始まる欠落しているメソッドのみをキャッチするようになりました。そこに少しロジックを追加して、不要なメソッドに対して super を呼び出すことを忘れないでください!
class Zoo
def animals
@@animals ||= []
end
def method_missing(method_name, *args, &block)
if method_name.to_s.start_with?('find_animals_by_')
find_animals_by_attribute(method_name[16..-1], args[0])
else
super(method_name, *args, &block)
end
end
def find_animals_by_attribute(attribute, value)
animals.select{ |animal| animal[attribute.to_sym] == value }
end
end
終わり!動物を検索できる完全に機能する動物園!