この猫の皮を剥ぐ方法はいくつかあります。1つはラムダを使用しています:
MATCHERS = [
[/^gnome|dwarf|hobbit$/, lambda { |a| 'dwarf' }],
['dragon', lambda { |a| puts 'run away!' }],
[/^centaur|unicorn$/, lambda { |a| magical_equine_function(a) }],
[//, lambda { |a| false }],
]
これにより、パターン (文字列または正規表現) がラムダに関連付けられます。最後のマッチャーは特別です。これは、何にでもマッチする歩哨です。これは、例のelse句の代わりになります。
マッチングを行うコードは次のとおりです。
def match(a)
MATCHERS.each do |pattern, f|
return f[a] if pattern === a
end
end
文字列または正規表現のいずれかを使用===
できるように使用します。
使用方法は次のとおりです。
p match('gnome')
# => "dwarf"
p match('dragon')
# => "run away!"
# => nil
p match('unicorn')
# => "equine unicorn"
p match('oddball')
# => false
メソッドでもそれを行うことができます:
class Matcher
def match(a)
MATCHERS.each do |pattern, method|
return send(method, a) if pattern === a
end
end
private
MATCHERS = [
[/^gnome|dwarf|hobbit$/, :dwarf],
['dragon', :dragon],
[/^centaur|unicorn$/, :equine],
[//, :default],
]
def dwarf(a)
"dwarf"
end
def dragon(a)
puts "run away!"
end
def equine(a)
magical_equine_function(a)
end
def default(a)
false
end
def magical_equine_function(a)
"equine #{a}"
end
end
そして使用中:
matcher = Matcher.new
p matcher.match('gnome')
# => "dwarf"
# etc.
メソッドを使用すると、コードがマッチング ルールから分離されるため、必要に応じてマッチング ルールをファイルに入れることができます。の内容は次のmatch_rules
とおりです。
---
- - !ruby/regexp /^gnome|dwarf|hobbit$/
- :dwarf
- - dragon
- :dragon
- - !ruby/regexp /^centaur|unicorn$/
- :equine
- - !ruby/regexp //
- :default
Matcher
これが機能するために、クラスに多くの変更を加える必要はありません。
require 'yaml'
class Matcher
def initialize
@matchers = YAML.load_file('match_rules')
end
def match(a)
@matchers.each do |pattern, method|
return send(method, a) if pattern === a
end
end
# ...
end
ファイルから on data you toを使用send
すると、ファイルを作成した人は誰でも、Matcher クラスのメソッドのいずれかを呼び出すことができます。これを防ぐには、ルールで使用されるすべてのメソッドにプレフィックスを追加するだけです。
def matched_dragon(a)
puts "run away!"
end
# etc.
そして、match メソッドで、そのプレフィックスを追加します。
def match(a)
@matchers.each do |pattern, method|
return send("matched_#{method}", a) if pattern === a
end
end
これで、"matched_" で始まるメソッドのみが match 関数によって呼び出されるようになりました。
コメントの後続の質問への回答:
文字列の配列であるパターンの YAML は次のようになります。
---
- - - gnome
- dwarf
- hobbit
- :small_person
- - - dragon
- :dragon