Ruby の `?` がつくメソッドの返り値を逆にする

More than 1 year has passed since last update.

エイプリルフールの時にネタで考えたやつです。

klasses = ObjectSpace.each_object(Module).reject(&:singleton_class?).sort_by(&:to_s)

methods = {}

klasses.reject! do |k|
methods[k] = k.instance_methods(false).select { |m| m.to_s.end_with?('?') } - [:respond_to?]
methods[k].empty?
end

klasses.each do |k|
k.class_eval(
methods[k].map do |name|
<<-EOF
alias_method "_
#{name}", :#{name}

def #{name}(*args, &block)
!_
#{name}(*args, &block)
end
EOF
end.join("\n")
)
end

p (1..10).include?(3) #=> false
p (1..10).include?(100) #=> true
p [1, 2, 3].all?(&:odd?) #=> true
p [1, 2, 3].any?(&:odd?) #=> false

各 Class, Moduleから最後に ? がつくメソッドを探し出して、返り値を反転させるようにメソッドを上書きしています。

respond_to? は書き換えると通常動作に大きく影響を与えてプログラムが落ちてしまったので除外しています。


Gem にしてみました

lier という名前でリリースしました。Module を refinements 出来るようになったのが 2.4 からなのでバージョンが 2.4以上の ruby でしか動かない gem になっています。(:warning: 本番環境で動かさないでください)

https://github.com/siman-man/lier