Skip to content

Instantly share code, notes, and snippets.

@aoitaku
Last active August 25, 2016 14:36
Show Gist options
  • Save aoitaku/d746cc9cd4b5ccd85046c31ffd5011d6 to your computer and use it in GitHub Desktop.
Save aoitaku/d746cc9cd4b5ccd85046c31ffd5011d6 to your computer and use it in GitHub Desktop.
このコードどうにかしてみました http://d.hatena.ne.jp/t_tutiya/20160822/1471881932
def _CHECK_(yield_stack, options, &block)
# Proc#[] は Proc#call の別名で、これを利用すると Hash#[] と同じように呼び出せるようになります
datastore = options[:_ARGUMENT_] ? @root_control.send(options[:_ARGUMENT_]) : proc {|key| send(key) }
# いずれかが真のときに true ということならここも any? が使えます
result = options.any? do |condition, value|
case condition
#指定されたデータと値がイコールかどうか
when :equal
value.any?{|key, val| datastore[key] == val}
#指定されたデータと値がイコールでない場合
when :not_equal
value.any?{|key, val| datastore[key] != val}
#指定されたデータと値が未満かどうか
when :under
value.any?{|key, val| datastore[key] < val}
#指定されたデータと値がより大きいかどうか
when :over
value.any?{|key, val| datastore[key] > val}
else
false
end
end
#チェック条件を満たす場合
if result
#ブロックを実行する
parse_block(options, yield_stack, &block)
end
end
end
def _CHECK_(yield_stack, options, &block)
datastore = options[:_ARGUMENT_] ? @root_control.send(options[:_ARGUMENT_]) : proc {|key| send(key) }
# 名前と演算子の対応テーブル
operators = {
equal: :==,
not_equal: :!=,
over: :>,
under: :<
}
# いずれかが真のときに true ということならここも any? が使えます
result = options.any? do {|condition, value|
# ブロック引数にシンボルをブロック化したものを渡すと第一引数をメソッドのレシーバに、
# 第二引数をメソッドの引数にしてメソッドを呼び出すブロックを渡せます
# value.flat_map{|k, v| [datastore[k], v]}.each_slice(2).any? {|k, v| k.send(operators[condition], v) }
# と同じような感じになります
operators[condition] && value.flat_map{|k, v| [datastore[k], v]}.each_slice(2).any?(&operators[condition])
end
#チェック条件を満たす場合
#ブロックを実行する
# 後置 if を使うかどうかは好みもあります
parse_block(options, yield_stack, &block) if result
end
end
@aoitaku
Copy link
Author

aoitaku commented Aug 25, 2016

any? にブロック渡さないために flat_map {}.each_slice するくらいなら any? にブロック渡すほうがいい気がしてきた

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment