Rubyで並列割り当てのための配列のようにオブジェクトの振る舞いをします
-
12-09-2019 - |
質問
あなたはRubyでこれを行うと仮定します:
ar = [1, 2]
x, y = ar
すると、X == 1とy == 2と同じ効果が得られます私は自分のクラスで定義することができます方法はありますか?例えばます。
rb = AllYourCode.new
x, y = rb
これまでのところ、私はこのような割り当てを行うことができましたすべては、x == RBとy = nilを作ることです。 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クラスは配列を継承した場合しかし、あなたの例では動作します。
Rubyが割り当てを検出すると、右側に見て、複数の右辺値がある場合は、それが配列にそれらを収集します。そして、それが左側に見えます。 1つの左辺値が存在する場合、それは配列が割り当てられます。
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が配列又は配列から継承する場合は、だからあなたの例では、xおよびyは、その最初の2つの値が割り当てられます。