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是 on 的一个实例方法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

如果您不知道您正在测试的对象是否将是一个字符串, Ramon建议您可能希望将您的扩展放在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 回答