【问题标题】:how to add syntactic sugar to rails similar to collections如何将语法糖添加到类似于集合的rails
【发布时间】:2012-04-01 11:48:56
【问题描述】:

如何添加类似于rails“添加到集合”的语法糖

@object.collection << item

我正在尝试做

class Object
  def collection<<(item)
    ...
  end
end

但它不起作用。或者,我想在属性上定义我自己的“运算符”。

注意 - 我知道使用 def &lt;&lt;(value) 很热门,但它适用于整个对象而不是它的属性。

【问题讨论】:

    标签: ruby-on-rails ruby syntax syntactic-sugar


    【解决方案1】:
    @object.collection << item
    

    让我们把它拆开。

    • @object - 好吧,有些对象。
    • collection - 当@object 被发送时 这个消息它返回一些东西。
    • &lt;&lt; - 此消息发送到 从collection 消息返回的对象。
    • item - &lt;&lt; 消息的参数。

    示例

    class Foo
      def << val
        puts "someone pushed #{val} to me"
      end
    end
    
    class Bar
      def collection
        @foo ||= Foo.new
      end
    end
    
    b = Bar.new
    
    b.collection << 'item'
    # someone pushed item to me
    

    顺便说一下,这些表单做同样的事情并产生同样的输出。

    b.collection << 'item'
    b.send(:collection).send(:<<, 'item')
    b.collection.<<('item')
    b.collection.<< 'item'
    

    【讨论】:

    • 虽然我喜欢你的解决方案,但仍然很遗憾,def @object.collection=(value) 是可能的 - 赋值是特权运算符:-)
    • 这是有原因的。 Getter/setter 是一个常见的习惯用法。半方法半运算符不是:)
    • add 运算符在 Rails 中仍然很常见,我希望它更容易调整。但我明白了原因。
    【解决方案2】:

    根据 Ruby 的工作原理,这是不可能的。您将需要您的集合方法来返回一个对象,该对象具有您的自定义 &lt;&lt; 方法。

    【讨论】:

    • 嗯,这就是我所说的,我只是没有使用“代理”这个词;)相反,我说的是“一个对象,上面有你的自定义 &lt;&lt; 方法”。但我赞成另一个答案,因为它比我给出的更详细
    【解决方案3】:

    &lt;&lt;Array 的一个方法,所以这适用于普通的 Ruby:

    def MyClass
      def initialize
        @collection = []
      end
      def collection
        @collection
      end
    end
    
    MyClass.new.collection << 'foo'
    

    【讨论】:

    • 我不想只添加到集合中 - 我将如何添加特殊行为,例如检查重复项等?
    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 2014-12-13
    • 2011-08-31
    • 1970-01-01
    • 2011-01-24
    • 2013-10-20
    • 2016-07-27
    • 2010-10-19
    相关资源
    最近更新 更多