3

splat 演算子のカスタム結果を書き込むには、to_aメソッドを実装する必要があります。String クラスの例:

class String
  def to_a
    self.split //
  end
end

irb> res = *'text'
=> ["t", "e", "x", "t"]

to_aしかし、上記のモンキーパッチがなければ、String クラスはメソッドについて何も知りません。

irb> String.respond_to? :to_a
=> false

問題は、標準の「パッチが適用されていない」文字列のオブジェクトに splat 演算子を適用すると、どのメソッドが呼び出されるかということです。

irb> res = *'text'
=> ['text']
4

3 に答える 3

5

最初に: を呼び出しても、文字列インスタンスがに応答するかどうかはわかりString.respond_to?(:to_a)ません。クラスがに応答するかどうかはわかります。文字列が に応答するかどうかを知りたい場合は、文字列に質問する必要があります。to_aString to_ato_a

'text'.respond_to?(:to_a) # => false

またはString、パブリック インスタンス メソッドがあるかどうかをクラスに問い合わせることもできto_aます。

String.public_instance_methods.include?(:to_a) # => false

s が応答しない理由は、何を求めているのかが明確でないためです。文字の配列が必要ですか? グリフの?行の?コードポイントの?バイトの?Stringto_a

a = *'text'.chars      # => ['a', 'b', 'c']
a = *'text'.codepoints # => [116, 101, 120, 116]
a = *'text'.bytes      # => [116, 101, 120, 116]
a = *'text'.lines      # => ['text']

splat 演算子が表示されているように動作する理由については、言語仕様のコーナー ケースのようです。これが意図された動作であるかどうかは 100% も確信が持てません。複数の割り当ての仕様は、ほぼ 4 ページにわたって実行されます。詳細については、Ruby 言語仕様のセクション 11.4.2.4 を参照してください。

于 2013-01-15T16:38:37.180 に答える
3

Splat は、定義により、オブジェクトが応答しない場合、配列で値を返しますto_a

it "assigns the splatted object contained into an array when the splatted object doesn't respond to to_a" do
  a = *1; a.should == [1]
end

警告: やや非公式ですが、比較的使用可能です。

于 2013-01-15T16:41:56.587 に答える
1

これがあなたのニーズに対して十分に崇高であるかどうかはわかりませんが、次のことができます。

1.9.3-p0 :008 > res = *'text'.chars
 => ["t", "e", "x", "t"]
于 2013-01-15T16:27:17.360 に答える