0

次の拡張機能を作成しました

class String
  def is_a_number? s  # check if string is either an INT or a FLOAT (12, 12.2, 12.23 would return true)
    s.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
  end
end

連鎖メソッドとして機能させるにはどうすればよいですか?

is_a_number?("10") # returns true
"10".is_a_number? # returns an error (missing arguments)

アップデート

回答してくれたsawa、mikej、Ramonに感謝します。提案どおり、クラスを Object に変更し、引数を取り除きました。

class Object
  def is_a_number?  # check if string is either an INT or a FLOAT (12, 12.2, 12.23 would return true)
    to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) != nil
  end
end

今では完全に正常に動作します:

23.23.is_a_number? # > true

みんなありがとう...

4

2 に答える 2

2

を記述すると、チェックしたい"10".is_a_number?オブジェクトが既にあり、これは のレシーバーであるため、メソッドはパラメーターを取る必要はありません。 "10"is_a_number?

matchは のインスタンス メソッドであるためString、レシーバーを指定する必要はありません。is_a_number?呼び出されたのと同じオブジェクトを操作するだけです。String既にオブジェクトがあることがわかっているため、to_sも必要ありません。

次のように書くだけです:

class String
  # check if string is either an INT or a FLOAT (12, 12.2, 12.23 would return true)
  def is_a_number? 
    match(/\A[+-]?\d+?(\.\d+)?\Z/) != nil
  end
end

テストするオブジェクトが文字列になるかどうかわからない場合は、拡張機能をオンにするのObjectではなくオンにすることをお勧めします。String


また、あなたが説明していることは、メソッドチェーンが意味するものではありません。オブジェクトのメソッドを呼び出すだけです。メソッドチェーンは、メソッドの戻り値の型が設定されているため、Rails などで複数のメソッドを順番に呼び出すことができます。

User.where(:name => 'Mike').limit(3) # find the first 3 Mikes

メソッドチェーンの例です。

于 2012-10-07T10:54:28.660 に答える
1

Object代わりにパッチを適用したいようですString(呼び出しているためto_s):

class Object
  def is_a_number?
    to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/).nil?
  end
end

validates numericality: trueあなたのモデルでそれを置き換えることもできます。

于 2012-10-07T10:58:25.070 に答える