棘手的ruby类init ----为什么同一个类初始化输出不同?

时间:2012-03-04 08:29:54

标签: ruby class

看这堂课:

class Test
  def initialize a, b, c
    @a = a, @b = b, @c = c
  end
  end

class AnotherTest
  def initialize a, b, c
    @a = a
    @b = b
    @c = c
  end
end

array = []

array.push Test.new "a1" ,"b1", "c1"
array.push AnotherTest.new "a2" ,"b2", "c2"

p array

我认为这应该是相同的,但不是:

<Test:0x000000022aba78 @b="b1", @c="c1", @a=["a1", "b1", "c1"]>
<AnotherTest:0x000000022ab9b0 @a="a2", @b="b2", @c="c2">]

任何可以给我解释的人?

4 个答案:

答案 0 :(得分:4)

如果您尝试使用此表达式:

a = "something" #=> "something"

正如您所看到的,赋值操作返回结果,因为在ruby中,每个表达式都应返回一些内容。那么这个表达式:

@b = b #=> b

将返回@b的值。然后在这个表达式

@a = a, @b = b, @c = c

其中@b = b@c = c将评估为bc

所以最后我们将有这个表达式:

@a = a, b, c

正如您所知,它是数组初始化的另一种形式

@a = [a, b, c]

此代码与您的代码等效:

class Test
  def initialize a, b, c
    @a = a, b, c
    @b = b
    @c = c
  end
end

增加: 评估的顺序很重要。 如果你试试这个表达式:

@a = a, (@b = b, @c = c)

首先,它将评估括号中的所有内容:

@b = b, @c = c #=> @b = [b,c] and @c = c

那么我们就会得到这个

@a = [a,[b,c]]
@b = [b,c]
@c = c

答案 1 :(得分:3)

并行分配如下所示:

@a, @b, @c = a, b, c

不仅仅是在ruby中,在所有并行分配的语言中看起来都是这样。

答案 2 :(得分:2)

@a正在使用一组值进行初始化。您可以编写a = 1, 2, 3a将分配列表[1, 2, 3]。因此,您的示例中的@a被指定为三个值'a1''b1''c1'的列表。

要将其分解,可将其视为@a = a, @b = b, @c = c

您可能想要的只是:

class Test       
  def initialize a, b, c       
    @a = a; @b = b; @c = c       
  end       
end   

答案 3 :(得分:1)

在Ruby中专门处理的赋值语句中的逗号。因此,上面的结果。

 @a = a, @b = b, @c = c

在上面的表达式中,Ruby首先看到=作为赋值语句的一部分。 Ruby将等于(rvalues)右侧的值视为逗号分隔值,因此,首先评估每个逗号分隔值。这会导致@b和@c被分配,这些表达式中的每一个也返回指定的值。

然后,由于@a是赋值语句左侧唯一的项,因此将rvalues视为数组,并将数组赋值为@a。值由a,b和c组成。这就是发生的事。

所以,如果你想要发生三个作业,那么,用分号分隔作业 让所有这些陈述让Ruby感到高兴。

请注意,您也可以在=的左侧声明多个项目。