• ベストアンサー

splitについて教えてください。

@name=("ひろと","けいた","はやと","りゅうすけ","とらのすけ"); @str=@name; print "@str\n"; @str=join(";",@str); print "<br>@str\n"; @str=split(/;/,@str); print "<br>@str\n"; 上記のような配列を作成したプログラムを実験で作ってみました。(一部抜粋です。htmlで表記されるようにしています。) ブラウザで見てみると、以下のようになりました。 ひろと けいた はやと りゅうすけ とらのすけ ひろと;けいた;はやと;りゅうすけ;とらのすけ 1 その中の3行目の「1」とだけ表示された理由がわかりません。 splitにより、joinで作成された一つの文字列を、 再び「;」で区切って要素数が5つの配列に戻したかったのですが、 なぜか1と返されてしまいました。 splitの使い方を教えていただけないでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

問題の2行を砕いてみます。 > @str = join(";", @str); ・join に渡される引数は、    ";", "ひろと", "けいた", "はやと", "りゅうすけ", "とらのすけ"  の6つです。 ・join の戻り値は    "ひろと;けいた;はやと;りゅうすけ;とらのすけ"  です。 ・@str で受け取ったので、    $str[0] = "ひろと;けいた;はやと;りゅうすけ;とらのすけ"  となります。(要素は1つだけ)  これはスカラ値を配列で受け取った場合の標準の動作であり、あまりやりませんが問題はありません。 > @str = split(/;/, @str); ・split に渡される引数は、    ";", "1"  です。  ここで @str の要素数が渡ってしまうのが「関数プロトタイプ」によるもの。 ・split は "1" という文字列を ";" で分割しようと試みますが、できないので ("1") というリストを返します。 ・@str で受け取ったので、    $str[0] = "1"  となります。(要素は1つだけ) このような過程となります。

shevy
質問者

お礼

ご丁寧にありがとうございます。 非常によくわかりました。 関数プロトタイプですね、しっかりと勉強したいと思います。 今回の回答は本当に参考になりました。 ありがとうございました!

その他の回答 (2)

  • the845t
  • ベストアンサー率33% (246/743)
回答No.2

Perlだとして、 それは配列の要素数が表示されているのでは? @name=("ひろと","けいた","はやと","りゅうすけ","とらのすけ"); @str=@name; print "@str\n"; $str=join(";",@str); print "<br>$str\n"; @str=split(/;/,$str); print "<br>@str\n"; これで良いかな?

shevy
質問者

お礼

ありがとうございました。 やはり、配列の要素数が表示されていたようです。 ありがとうございました。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

join の結果は1つの文字列なので、   @str = join(";", @str); によって @str の要素が1つだけになることは分かりますよね? 問題の split の方ですが、   @str = split(/;/, @str); これは普通に考えれば、split の2番目の引数として @str の1番目の要素(つまり $str[0])を指定したことになると思います。 ところが一部の組み込み関数は、「関数プロトタイプ」という「引数の型を規定する機能」によって、そうならないことがあるんです。 split は2番目の引数をスカラ値と定めているので、2番目に書かれた引数はスカラコンテキストで評価されます。 配列をスカラコンテキストで評価すると要素数が得られますから、上記スクリプトでは要素数である「1」という値が関数に渡るため、結果 1 と表示されるのです。 ・・・ちょっと難しかったですね^^; で join & split の使い方ですが、join の戻り値はスカラ変数($var)で受け取り、それを split に渡す、というの一般的です。   @str = join(";", @str);   print "<br>@str\n";   @str = split(/;/, @str); の3行を   $str = join(";", @str);   print "<br>$str\n";   @str = split(/;/, $str); と変えてください。

shevy
質問者

お礼

ありがとうございます。 序盤の説明が少し??となって、理解に苦しんでいますが、 joinにおいて、スカラ変数として格納するので、 $strだというのはよくわかりました。 当然、帰結してくるsplitにおいても、 スカラ変数からリストコンテキストへの移動なので、 $から@にすべきですよね。 非常にイメージしやすかったです。 >配列をスカラコンテキストで評価すると要素数が得られますから、上記スクリプトでは要素数である「1」という値が関数に渡る ここまでは、ほぼ完璧に理解いたしました。 @strは、スカラコンテキストで評価すると、既にjoinにより一つの文字列化されているので、 1になるというのはわかります。 ただ、それを@strに代入するということ自体が、 どうも腑に落ちないというか、ありえないことをしている?ような気がします。 @なので、やはりリストコンテキストで表示されるべき気もしますが、 すでに値はスカラコンテキストで返されるという決まりにより「1」になっており、その「1」という数字自体を 配列の要素(添え字ではない)だと考えるのかなと思っています。 つまり@strは要素数が1で、中身も1である。 返された値は中身の1である。 という気がしますが、どうでしょうか?

関連するQ&A