【发布时间】:2011-05-26 21:02:47
【问题描述】:
有没有更好的方法来获取 Ruby 对象的公共“属性”?
def props
self.public_methods.grep(/.=$/) - ["==","==="]
end
【问题讨论】:
标签: ruby reflection metaprogramming
有没有更好的方法来获取 Ruby 对象的公共“属性”?
def props
self.public_methods.grep(/.=$/) - ["==","==="]
end
【问题讨论】:
标签: ruby reflection metaprogramming
您的正则表达式不完整:它匹配以任何字符开头的方法,而不仅仅是单词字符。获得所有“作家”的最佳方式是
methods.grep /^\w+=$/
并且正则表达式可以缩短为
methods.grep /\w=$/
但不太清楚。
【讨论】:
^,所以它匹配任意长度的方法名。
^表示字符串或行的开头,这与字符串的长度完全无关,尤其是在只有一行的方法名中不重要。跨度>
["[]=", ">=", "<=", "!="] 将被错误地包含在内,这确实是。但是 Tyndall 的正则表达式不仅匹配仅由单个字符和等号组成的方法。
在 ruby 中,除非您执行元编程来破坏封装,否则更改另一个对象的实例变量的唯一方法是调用碰巧这样做的方法。如果不使用元编程,就无法判断某个方法正在更改哪个实例变量。
例如,如果我有一个人,并且该类中有 height_feet= 和 height_meters= 方法,我将无法判断该人的身高的实现是基于 @height_feet 还是@height_meters 甚至是@height_cubits。
这是一件好事,因为这意味着您仅针对接口而不是实现进行编程。
【讨论】:
嗯,Ruby 中没有“属性”这样的东西。基本上,既然你创造了这个词(或者更准确地说:你创造了它适用于 Ruby 的定义),你就可以定义它的含义,但另一方面,它也意味着你必须自己实现它的语义。
因此,如果您将“属性”定义为“以等号结尾但不完全由等号组成的方法”,那么,是的,您的定义是最好的方法。 (顺便说一句:您对“财产”的定义包括 <=、>= 和 != 等方法,这可能是您想要的,也可能不是。)
【讨论】:
Array#length 是属性吗? String#length 怎么样,它实际上必须沿着整个字符串走?