2012-10-07 50 views
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) 

更新

感谢泽,mikej和拉蒙对他们的答案。至于建议,我改变了类对象,并摆脱了参数(或多个):

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 

感谢球员...

回答

2

当你写"10".is_a_number?,你已经有了要检查的对象"10",这是is_a_number?的接收器,所以你的方法不需要带任何参数。

因为matchString上的实例方法,所以不需要为它指定接收方。它只会在调用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's建议,你可以把它放到你的扩展上Object而非String是一个很好的点,如果你不知道,如果你正在测试的对象是将成为一个字符串。


此外,什么你所描述的是不是真的什么是方法链接的意思;它只是调用一个对象的方法。方法链是其中的方法的返回类型设置,使几种方法可以在Rails的序列e.g叫,像

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

是方法链的一个例子。

1

好像要修补Object,而不是String(因为你在呼唤to_s):

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

你也可以看看它与validates numericality: true您的型号更换。