【问题标题】:Is there a better way to get the public "properties" of a Ruby object?有没有更好的方法来获取 Ruby 对象的公共“属性”?
【发布时间】:2011-05-26 21:02:47
【问题描述】:

有没有更好的方法来获取 Ruby 对象的公共“属性”?

def props
  self.public_methods.grep(/.=$/) - ["==","==="]
end

【问题讨论】:

    标签: ruby reflection metaprogramming


    【解决方案1】:

    您的正则表达式不完整:它匹配以任何字符开头的方法,而不仅仅是单词字符。获得所有“作家”的最佳方式是

    methods.grep /^\w+=$/
    

    并且正则表达式可以缩短为

    methods.grep /\w=$/
    

    但不太清楚。

    【讨论】:

    • 正则表达式开头没有^,所以它匹配任意长度的方法名。
    • 正则表达式中的^表示字符串或行的开头,这与字符串的长度完全无关,尤其是在只有一行的方法名中不重要。跨度>
    • @Refactor:我的意思是指 tyndall 的正则表达式,而不是你的正则表达式。我的意思是说它已经匹配了所有的“作家”。
    • @Andrew Grimm:如果您指的是 Tyndall 的正则表达式已经匹配所有“作家”,那么您可能忘记了真正的“作家”实际上需要以单词字符开头而不是任何东西(@ 987654325@).
    • @Refactor:这意味着["[]=", ">=", "<=", "!="] 将被错误地包含在内,这确实是。但是 Tyndall 的正则表达式不仅匹配仅由单个字符和等号组成的方法。
    【解决方案2】:

    在 ruby​​ 中,除非您执行元编程来破坏封装,否则更改另一个对象的实例变量的唯一方法是调用碰巧这样做的方法。如果不使用元编程,就无法判断某个方法正在更改哪个实例变量。

    例如,如果我有一个人,并且该类中有 height_feet=height_meters= 方法,我将无法判断该人的身高的实现是基于 @height_feet 还是@height_meters 甚至是@height_cubits

    这是一件好事,因为这意味着您仅针对接口而不是实现进行编程。

    【讨论】:

    • 那么如果你想序列化对象或者写一个数据映射器......最常见的做法是什么?最简单的方法?
    • @tyndall:我认为这是一个单独的问题。
    【解决方案3】:

    嗯,Ruby 中没有“属性”这样的东西。基本上,既然你创造了这个词(或者更准确地说:你创造了它适用于 Ruby 的定义),你就可以定义它的含义,但另一方面,它也意味着你必须自己实现它的语义。

    因此,如果您将“属性”定义为“以等号结尾但不完全由等号组成的方法”,那么,是的,您的定义是最好的方法。 (顺便说一句:您对“财产”的定义包括 <=>=!= 等方法,这可能是您想要的,也可能不是。)

    【讨论】:

    • 我想我的意思是属性。已公开(公共)的类内部变量。正在查看 YAML 标准库代码,但找不到在这些代码上循环的位置。我确定它在那里,但我找不到它。
    • @tyndall:波塔托,波塔托。这是同一件事。 “属性”只是一个 social 构造。方法是一个属性,因为您决定调用一个属性。没有算法、程序、方法、过程、函数可以确定任何特定方法是否是属性,因为确定它是否属性的唯一事物不是某种技术特征至于方法本身,只是是否想称它为属性。 Array#length 是属性吗? String#length 怎么样,它实际上必须沿着整个字符串走?
    猜你喜欢
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2010-11-11
    相关资源
    最近更新 更多