did_you_meanを使ってtypoしても動くようにしています。
fuzzy_ruby.rb
# require RUBY_VERSION >= '2.3.0'
class Object
Ex = Struct.new(:name, :receiver, :args)
def method_missing(name, *args, &block)
methods = DidYouMean::MethodNameChecker.new(Ex.new(name.to_s, self, [])).corrections
if methods.empty?
super
else
self.send(methods.first, *args, &block)
end
end
end
# "hello".chars.join.upcase を全部typoしても動く
p "hello".chas.jooin.upcas
出力
"HELLO"
説明
did_you_meanはRuby2.3から標準で組み込まれたライブラリで、typoしたときに正しそうなメソッド名や変数名等を教えてくれます。
上のコードでは method_missing
を使ってtypoしたときの情報を取り出し、それを MethodNameChecker
に渡して上げることで正しそうなメソッド名の一覧を取得しています。もし、候補が存在する場合は send
メソッドを使って再度実行します。(複数候補がある場合は一番最初のものを選択)
注意
出力に p
ではなく puts
を使う場合は下記のようなエラーが出ることがあると思うので、そのときは methods から :to_r
を外してください。
`puts': can't convert Integer to Array (Integer#to_ary gives Rational) (TypeError)
:to_r
を外して対処
methods -= [:to_r]
もうちょっと細かく話すと、puts は文字列と配列以外のオブジェクトが渡された時に、最初は to_ary
を使って配列への変換を試みるのですが、その時に to_ary
を持っていない場合は今回のコードによって to_r
がサジェストされ、それを実行してしまいます。to_ary
は内部的には配列以外の戻り値を認めていないので、それによってエラーが発生します。