3

有时我需要这样的方法,它可以改变自己对象的类。有String#delete!, #downcase!, #encode!, #gsub!, #strip!,#slice!等。它们都在尝试更改字符串,但结果类仍然是String. 我想要一个方法,它可以转换StringArray. 一些方法来做到这一点:

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

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

4

3 回答 3

11

不,不可能。对象不能在 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:,它将字符串拆分为子字符串数组。结果是一样的:原来的字符串接收器现在是一个数组。

于 2010-09-25T05:33:57.033 回答
0

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

否则,为您的字符串提供一个内部数组,并使其将所有消息委托给该数组(沿着BlankSlate + Forwardable的行)。

这仍然不是我想做的事情。我无法想象这样一种小便利超过了实现的骇人听闻的情况。

于 2010-09-29T06:24:42.607 回答
0

Jörg W Mittag 的回答是可靠的。它是 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"]
于 2010-09-29T06:02:37.357 回答