2010-12-07 109 views
2

我们的应用使用send方法来调用我们的对象上的函数。 不幸的是,有些时候,传递给send的字符串可能不是Ru​​by中的合法方法名称。有谁知道会允许我们检查这个的正则表达式吗?什么是Ruby正则表达式来匹配函数名称?

合法的,我的意思是一个不以“?”开头的方法名称等。我不在乎对象是否响应该方法,因为在这种情况下我们使用method_missing,而且我们实际上想要它将被使用,这只会发生在对象没有响应的方法上。

从技术上讲,我正在寻找这does this一个正则表达式:

红宝石标识符包括 字母,十进制数字和 下划线,并用 字母(包括下划线)开始。 对 Ruby标识符的长度没有限制。

+0

我想有在SO关于正则表达式的一个问题来匹配一个变量名,which'd与这个问题有点相关,但我找不到它。 – 2010-12-07 22:30:46

回答

14

您可以利用Symbol#inspect在不是有效标识符时引用该名称的事实。检查时有效的符号变成":hello!",但无效的符号变成":\"invalid!?\""。这处理异国情调的符号,如:foo=:[]=和任何其他有效的方法名称。

添加额外的要求,即@ -names是有效的标识符,但不是有效的方法名给了我们这样的:

class Symbol 
    def method_name? 
    return /[@$"]/ !~ inspect 
    end 
end 
4

如果它是一个合法的方法名称,但该方法实际上并不存在于您试图发送它的对象上?

无论采用哪种方式,您都应该在尝试调用该方法之前检查对象是否响应某个方法,而不管该字符串是否为合法的方法名称。您可以通过使用Object#respond_to?方法来完成此操作。

例如:

obj = Person.new 
method = "set_name" 

if obj.respond_to?(method) 
    obj.send(method, "foo") 
end 

如果你想确保一个字符串是你想要使用正则表达式..像/^([a-zA-Z_]+|\[\])[\?!=]?$/应该用于一般方法的工作一个合法的方法名。不管我的观点还是主张要确保这个对象响应方法名

+0

合法方法名称是被Ruby识别为方法名称的方法...例如'?echo`不是合法的方法名称。 – 2010-12-07 16:14:12

+1

对,我在说你应该在调用它之前检查对象是否响应该方法。在投票前你有没有尝试过? – 2010-12-07 16:16:29

+1

+1抵消愚蠢downvoting – ryeguy 2010-12-07 16:19:10

0

我不太确定的正则表达式是去这里的路,但这里的一个尝试

def could_be_method_name?(m) 
    match = /^([a-zA-Z_]([\w]*[\w!?=]$){0,1})/.match(m) 
    return match == nil ? false : match[1].length==m.length 
end 

Ruby的方法名必须以启动字母或下划线。它们只能包含字母数字字符,但最后一个字符也可以是!,?或=。

1

允许在源代码的Ruby方法标识符可以由该匹配:

# Yes, upper-case first letters are legal 
/\A(?:[a-z_]\w*[?!=]?|\[\]=?|<<|>>|\*\*|[!~+\*\/%&^|-]|[<>]=?|<=>|={2,3}|![=~]|=~)\z/i 

然而,请注意,方法可以被定义为不匹配这样的模式:

class Foo 
    define_method("!dumb~name"){ puts "yup" } 
end 
Foo.new.send('!dumb~name') 
#=> yup 

编辑 :更新后添加全部Operator Expressions