重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

@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の使い方を教えていただけないでしょうか。

A 回答 (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つだけ)

このような過程となります。
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます。

非常によくわかりました。
関数プロトタイプですね、しっかりと勉強したいと思います。

今回の回答は本当に参考になりました。
ありがとうございました!

お礼日時:2003/04/17 09:04

Perlだとして、


それは配列の要素数が表示されているのでは?

@name=("ひろと","けいた","はやと","りゅうすけ","とらのすけ");
@str=@name;
print "@str\n";
$str=join(";",@str);
print "<br>$str\n";
@str=split(/;/,$str);
print "<br>@str\n";
これで良いかな?
    • good
    • 0
この回答へのお礼

ありがとうございました。

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

お礼日時:2003/04/17 09:05

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);
と変えてください。
    • good
    • 0
この回答へのお礼

ありがとうございます。

序盤の説明が少し??となって、理解に苦しんでいますが、

joinにおいて、スカラ変数として格納するので、
$strだというのはよくわかりました。
当然、帰結してくるsplitにおいても、
スカラ変数からリストコンテキストへの移動なので、
$から@にすべきですよね。
非常にイメージしやすかったです。


>配列をスカラコンテキストで評価すると要素数が得られますから、上記スクリプトでは要素数である「1」という値が関数に渡る

ここまでは、ほぼ完璧に理解いたしました。
@strは、スカラコンテキストで評価すると、既にjoinにより一つの文字列化されているので、
1になるというのはわかります。

ただ、それを@strに代入するということ自体が、
どうも腑に落ちないというか、ありえないことをしている?ような気がします。
@なので、やはりリストコンテキストで表示されるべき気もしますが、
すでに値はスカラコンテキストで返されるという決まりにより「1」になっており、その「1」という数字自体を
配列の要素(添え字ではない)だと考えるのかなと思っています。

つまり@strは要素数が1で、中身も1である。
返された値は中身の1である。

という気がしますが、どうでしょうか?

お礼日時:2003/04/16 21:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!