我们的应用使用send
方法调用对象上的函数。
不幸的是,有时传递给send
的字符串可能不是Ruby中的合法方法名称。有没有人知道可以让我们检查这个的正则表达式?
通过合法,我的意思是一个不以“?”开头的方法名称,等等。我不关心对象是否响应该方法,因为在这种情况下我们使用method_missing
,并且我们实际上希望它被使用,这只会发生在对象没有响应的方法中。
从技术上讲,我正在寻找does this:
的正则表达式Ruby标识符由 字母,十进制数字和 强调字符,并以a开头 字母(包括下划线)。那里 对长度没有限制 Ruby标识符。
答案 0 :(得分:15)
当Symbol#inspect
不是有效标识符时,您可以利用":hello!"
引用该名称的事实。检查时有效符号变为":\"invalid!?\""
,但无效符号变为:foo=
。这可以处理奇异符号,例如:[]=
,@
和任何其他有效的方法名称。
添加class Symbol
def method_name?
return /[@$"]/ !~ inspect
end
end
- 名称是有效标识符但不是有效方法名称的附加要求给出了以下内容:
{{1}}
答案 1 :(得分:4)
如果它是一个合法的方法名称,但该方法实际上并不存在于您尝试将其发送到的对象上,该怎么办?
无论哪种方式,您都应该在尝试调用方法之前检查对象是否响应方法,无论字符串是否为合法方法名称。您可以使用Object#respond_to?
方法执行此操作。
例如:
obj = Person.new
method = "set_name"
if obj.respond_to?(method)
obj.send(method, "foo")
end
如果你想确保一个字符串是一个合法的方法名,你想要使用正则表达式。像/^([a-zA-Z_]+|\[\])[\?!=]?$/
这样的东西应该适用于一般方法。无论我的观点仍然代表确保此对象响应方法名称
答案 2 :(得分: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。
答案 3 :(得分:0)
我不太确定regexp是去这里的方法,但这是一次尝试
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方法名称必须以字母或下划线开头。它们只能包含字母数字字符,但最后一个字符也可以是!,?或=。