使一个对象表现得就像在红宝石平行分配的数组
-
12-09-2019 - |
题
假设你在Ruby中做到这一点:
ar = [1, 2]
x, y = ar
然后,X == 1和y == 2是否有一个方法我可以在自己的类定义将产生同样的效果? e.g。
rb = AllYourCode.new
x, y = rb
到目前为止,我已经能够用这样的赋值操作是使X == RB和y =零。 Python有一个特征是这样的:
>>> class Foo:
... def __iter__(self):
... return iter([1,2])
...
>>> x, y = Foo()
>>> x
1
>>> y
2
解决方案
是的。定义#to_ary
。这将让你的对象可作为用于分配的阵列处理。
irb> o = Object.new
=> #<Object:0x3556ec>
irb> def o.to_ary
[1, 2]
end
=> nil
irb> x, y = o
=> [1,2]
irb> x
#=> 1
irb> y
#=> 2
和#to_a
之间#to_ary
的区别在于#to_a
用于尝试转换
一个给定的对象阵列,而#to_ary
可用如果我们可以把给定的对象为一个数组。这是一个微妙的差异。
其他提示
几乎:
class AllYourCode
def to_a
[1,2]
end
end
rb = AllYourCode.new
x, y = *rb
p x
p y
啪将尝试调用to_ary
,然后尝试调用to_a
。我不知道你为什么要做到这一点,虽然,这是一个真正的语法功能,恰巧使用Array
在执行,而不是Array
的功能。
在换句话说,用例多重分配是一样的东西:
# swap
x, y = y, x
# multiple return values
quot, rem = a.divmod(b)
# etc.
name, age = "Person", 100
在换句话说,大部分的对象从(所述Array
)被分配的时刻甚至没有明显。
可以不重新定义分配,因为它是一个运算符代替的方法。但是,如果你AllYourCode类是从Array继承,你的例子会工作。
当红宝石遇到分配,它看起来在右侧,并且如果存在一个以上的右值,它收集它们到一个数组。然后,它着眼于左侧。如果有一个左值那里,它被分配的阵列。
def foo
return "a", "b", "c" # three rvalues
end
x = foo # => x == ["a", "b", "c"]
如果有多于一个的左值(更具体地,如果它认为逗号),它依次分配右值和丢弃多余的。
x, y, z = foo # => x == "a", y == "b", z == "c"
x, y = foo # => x == "a", y == "b"
x, = foo # => x == "a"
您可以做平行分配如果返回一个数组,也因为你已经发现了。
def bar
["a", "b", "c"]
end
x = bar # => x == ["a", "b", "c"]
x, y, z = bar # => x == "a", y == "b", z == "c"
x, y = bar # => x == "a", y == "b"
x, = bar # => x == "a"
因此,在你例如,如果RB为数组或从Array,x和y继承将被分配其第一2个值。
不隶属于 StackOverflow