Ruby 替换其中对象的通用方法';他自己的方法

Ruby 替换其中对象的通用方法';他自己的方法,ruby,Ruby,使用字符串可以做到这一点: a = "hello" a.upcase! p a #=> "HELLO" 但是,我如何编写自己的方法呢 比如(尽管这显然不起作用): 我知道有一些技巧可以在字符串上使用,但如果我尝试对对象执行类似操作,该怎么办?赋值或局部变量绑定(使用=运算符)内置于核心语言中,无法覆盖或自定义它。您可以在Ruby代码上运行预处理器,将您自己的自定义语法转换为有效的Ruby。您还可以将绑定传递给自定义方法,该方法可以动态地重新定义变量。不过,这不会达到您所期望的效果 要明白

使用字符串可以做到这一点:

a = "hello"
a.upcase!
p a #=> "HELLO"
但是,我如何编写自己的方法呢

比如(尽管这显然不起作用):


我知道有一些技巧可以在字符串上使用,但如果我尝试对对象执行类似操作,该怎么办?

赋值或局部变量绑定(使用
=
运算符)内置于核心语言中,无法覆盖或自定义它。您可以在Ruby代码上运行预处理器,将您自己的自定义语法转换为有效的Ruby。您还可以将
绑定
传递给自定义方法,该方法可以动态地重新定义变量。不过,这不会达到您所期望的效果


要明白,
self=
永远不会起作用,因为当你说
a=“string”;a=“另一个字符串”
您没有修改任何对象;您正在将局部变量重新绑定到其他对象。在自定义方法中,您处于不同的作用域中,您绑定的任何局部变量都将只存在于该作用域中;它不会对调用方法的范围产生任何影响。

您不能将self更改为指向其当前对象以外的任何对象。您可以对实例变量进行更改,例如在将基础字符更改为大写的大小写字符串中

正如在这一答复中指出的那样:


这里提到的一个技巧是一种变通方法,即将类作为另一个对象的包装器来编写。然后您的包装器类可以随意替换包装的对象。不过,我还是不敢说这是个好主意。

好吧,
倒过来
方法不更改对象标识,它只更改其内部结构(
s.object\u id==s.upcase!.object\u id


另一方面,数字是不可变的对象,因此,如果不更改它们的标识,就无法更改它们的值。好了,一个对象没有办法自我改变它的身份,但是,当然,你可以实现
positify改变对象属性的方法-这将是一个类似于upcase的方法!不适用于字符串。

许多类是不可变的(例如,
Numeric
Symbol
,…),因此没有方法允许您更改它们的值

另一方面,任何
对象
都可以有实例变量,并且可以修改这些变量

有一种简单的方法可以将行为委托给一个已知的对象(例如
42
),并能够在以后使用将其更改为另一个对象。在下面的示例中,
quacks\u like\u int
的行为类似于
Integer

require 'delegate'
quacks_like_an_int = SimpleDelegator.new(42)
quacks_like_an_int.round(-1) # => 40
quacks_like_an_int.__setobj__(666)
quacks_like_an_int.round(-1) # => 670
您也可以使用它来设计类,例如:

require 'delegate'
class MutableInteger < SimpleDelegator
  def plus_plus!
    __setobj__(self + 1)
    self
  end

  def positify!
    __setobj__(0) if self < 0
    self
  end
end

i = MutableInteger.new(-42)
i.plus_plus! # => -41
i.positify! # => 0
需要“委托”
类MutableInteger-41
i、 定位!#=>0
require 'delegate'
class MutableInteger < SimpleDelegator
  def plus_plus!
    __setobj__(self + 1)
    self
  end

  def positify!
    __setobj__(0) if self < 0
    self
  end
end

i = MutableInteger.new(-42)
i.plus_plus! # => -41
i.positify! # => 0