Rubyで並列割り当てのための配列のようにオブジェクトの振る舞いをします

StackOverflow https://stackoverflow.com/questions/766712

  •  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つの値が割り当てられます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top