一种实现`String#split!`的方法

时间:2010-09-25 05:19:08

标签: ruby class self-modifying

有时我需要这样的方法,它可以改变自己对象的类。有String#delete!#downcase!#encode!#gsub!#strip!#slice!等等。他们都在尝试更改字符串,但结果是无论如何,课程仍然是String。我想要一种可以将String转换为Array的方法。 一些方法:

irb(main):082:0> str = "qwerty"
=> "qwerty"
irb(main):083:0> str.split! "e"
=> ["qw", "rty"]
irb(main):084:0> str
=> ["qw", "rty"]

有可能吗?也许是一些很酷的日本功夫或丑陋的自行车 - 我希望看到任何解决方案。

3 个答案:

答案 0 :(得分:10)

不,不可能。对象不能在Ruby中更改它们的类。

例如,在Smalltalk中,您可以使用become:

becomeSubStrings: aString
    self become: (self subStrings: aString).

如果你这样称呼它:

s := 'qwerty'.
s becomeSubStrings: 'e'.

现在,s是一个数组:

Transcript show: s printString.

结果是:

#('qw' 'rty')

从技术上讲,become:不会更改对象的类,而是让一个对象成为另一个对象。在这种情况下,我们让self成为self subStrings:的结果,它将字符串拆分为子串数组。结果是一样的:原始字符串接收器现在是一个数组。

答案 1 :(得分:0)

JörgWMittag的答案很可靠。它是Ruby作为一种语言的基本属性,你无法改变对象的类。

您可以做的最好是重新分配变量,因为我相信您已经在做了:

irb(main):082:0> str = "qwerty"
=> "qwerty"
irb(main):083:0> str = str.split "e"
=> ["qw", "rty"]
irb(main):084:0> str
=> ["qw", "rty"]

答案 2 :(得分:0)

这只能使用evil-ruby(至少我很确定evil-ruby支持这个)。这是一个非常聪明的黑客,它哄骗Ruby做一些它从未打算做的事情,但也是一个不可移植的hack,已知它会导致使用它的Ruby代码中的实际段错误。你绝对不应该在生产代码中使用它。

否则,给你的字符串一个内部数组,并让它将所有消息委托给数组(沿BlankSlate + Forwardable行。)

这仍然不是我想做的事情。我无法想象这种轻微的便利性会超过实施的黑客程度。