代码之家  ›  专栏  ›  技术社区  ›  fl00r

Ruby重写<<方法

  •  0
  • fl00r  · 技术社区  · 15 年前

    class A

    class A
      attr_reader :b
      def b=param
        @b = param
        print "success"
      end
    end
    
    >> a = A.new
    >> a.b = "hello world!"
    #> "success"
    #> "hello world!"
    >> a.b << " and goodbye!"
    #> "helo world! and goodbye!"
    

    我的“成功”在哪里?:)

    每次变量改变时,我都想打印“success”。

    我不能就这么写

    def b<<param
      @b << param
      print "success"
    end
    
    3 回复  |  直到 15 年前
        1
  •  5
  •   Community Mohan Dere    9 年前

    @b 不变 在你的例子中。它仍然包含最初设置为的字符串对象。它是 弦本身 这正在改变。这种区别是非常重要的,如果你不理解它,你会发现你的程序被一千个细微的错误所困扰。这里是:

    对象和变量是两个独立的东西。变量就像插槽,对象就是你放进去的东西。只有 = operator将一个新对象放入插槽*;其他所有内容都将消息发送到插槽中的对象。当你写作时 @thing = "hello" ,将字符串对象 "hello" 插入槽中 @thing @thing << " world" ,您没有设置 @东西 包含一个新的对象;你把同一个对象留在那里,但是 " world" 在对象所表示的字符串的末尾。这也意味着,任何其他插槽持有相同的对象也会发现他们的字符串更改!

    如果你想避开这个问题,你必须使用一个代理对象(来接收 << 信息)喜欢 ormuriauga described 而不是直接存储字符串。鲁比的 Delegator

    *好吧,那有点手摇。还有特别的 instance_variable_set 可以设置实例变量的方法。但如果不使用 = 操作人员 eval() .

        2
  •  1
  •   einarmagnus    15 年前

    你必须 b

    尽管实际上你可以这样做:

    class A
      attr_reader :b
      def initialize
          @b = ""
          augment_b!
      end
    
      def augment_b!
          class << @b
            alias_method :ltlt, :<< 
            def << args
              self.ltlt args
              print "success"
            end
          end
      end
      def b=param
        @b = param.to_s
        augment_b!
        print "success"
      end
    end
    

    看看我能不能给你解释一下。

    b= 方法时调用 财产。但是当你打电话 a.b << 你正在访问b然后打电话 << 在那个物体上,因此只有在 A 访问时类 . 我所做的就是重新定义它 << 方法打开 .

        3
  •  0
  •   DigitalRoss    15 年前

    你的方法 b 在告别线上没有被叫来。

    << 类字符串的方法。

    您定义了两个名称相似的方法:一个是 另一个是 b= .

    乙= . 试试这个:

    a.b = "hello world!"
    success=> "hello world!"
    a.b = '' << " and goodbye!"
    success=> " and goodbye!"
    
    推荐文章