Ruby重写<&书信电报;方法

Ruby重写<&书信电报;方法,ruby,Ruby,我有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!" A类

我有
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!"
A类
属性读取器:b
def b=参数
@b=参数
打印“成功”
结束
结束
>>新的
>>a.b=“你好,世界!”
#>“成功”
#>“你好,世界!”
>>a.b“helo world!再见!”
我的“成功”在哪里

每次变量更改时,我都要打印“success”

我不能只是写

def b<<param
  @b << param
  print "success"
end

defb您必须使
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
A类
属性读取器:b
def初始化
@b=“”
增广!
结束
def增强!

class您必须使
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
A类
属性读取器:b
def初始化
@b=“”
增广!
结束
def增强!

class你的方法
b
没有在再见线上调用


调用了您定义的零参数访问器方法,并将返回的字符串传递给
您的方法
b
未在再见行上调用


调用了您定义的零参数访问器方法,并将返回的字符串传递给
,这里是您缺少的棘手部分:在您的示例中,变量
@b
不会更改。它仍然包含最初设置为的字符串对象。变化的是字符串本身。这种区别是非常重要的,如果你不掌握它,你会发现你的程序被上千个微妙的错误所困扰。这是:


对象和变量是两个独立的东西。变量就像插槽,对象就是你放进去的东西。只有
=
操作符将新对象放入插槽*;其他所有内容都会向插槽中的对象发送消息。当您编写
@thing=“hello”
时,将字符串对象
“hello”
放入插槽
@thing
。当您编写
@thing时,您缺少了一个棘手的部分:在您的示例中,变量
@b
不会改变。它仍然包含最初设置为的字符串对象。变化的是字符串本身。这种区别是非常重要的,如果你不掌握它,你会发现你的程序被上千个微妙的错误所困扰。这是:


对象和变量是两个独立的东西。变量就像插槽,对象就是你放进去的东西。只有
=
操作符将新对象放入插槽*;其他所有内容都会向插槽中的对象发送消息。当您编写
@thing=“hello”
时,将字符串对象
“hello”
放入插槽
@thing
。当你写
@东西的时候,不知何故它就变成了
b
。调用什么方法来分配?我想是setter,所以在setter中我调用
print
Ok,我添加了一个更新。有趣的是,注意到使用嵌入空格创造性地解析方法名。正如我前面提到的,如果我无法控制实例变量状态并通过方法进行更改,这是非常奇怪的,因为
=
对于我来说,这样做更简单:
a.b='hi';a、 b=a.b+“bye”
-但它不酷:),我的变量不是字符串,而是Arrayall
attr\u访问器:b
做的是:def b@Bend`and
def b=(_b)@b=_b;结束
。如果你想要别的东西,你必须做别的事情:)但不知何故,这就等于是
b
。调用什么方法来分配?我想是setter,所以在setter中我调用
print
Ok,我添加了一个更新。有趣的是,注意到使用嵌入空格创造性地解析方法名。正如我前面提到的,如果我无法控制实例变量状态并通过方法进行更改,这是非常奇怪的,因为
=
对于我来说,这样做更简单:
a.b='hi';a、 b=a.b+“bye”
-但它不酷:),我的变量不是字符串,而是Arrayall
attr\u访问器:b
做的是:def b@Bend`and
def b=(_b)@b=_b;结束
。如果你想做其他事情,你必须做其他事情:)a.b
SystemStackError:stack level太深了
yeah,对不起。现在修好了。测试itlooks是否太黑了:)Ruby不是用更简单的方法来检查实例变量的访问和更改吗?是的,它太黑了。就像我说的,我不推荐。如果你把这个物体给别人,你就不能用我所知道的任何简单的方法检测到变化。你想达到什么目的?a.b
SystemStackError:堆栈级别太深
是的,对不起。现在修好了。测试itlooks是否太黑了:)Ruby不是用更简单的方法来检查实例变量的访问和更改吗?是的,它太黑了。就像我说的,我不推荐。如果你把这个物体给别人,你就不能用我所知道的任何简单的方法检测到变化。你想实现什么?除了
实例变量集
,还有
实例评估
。但这是你不需要使用的黑魔法。除了
instance\u variable\u set
,还有
instance\u eval
。但那是你不需要使用的黑魔法。