質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Q&A

解決済

2回答

2548閲覧

Perl:グローバル変数とローカル変数?

UMA00

総合スコア18

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

0グッド

1クリップ

投稿2016/10/08 13:17

編集2016/10/08 13:19

###前提・実現したいこと
関数呼び出しにより、ファイルの中身を1行ずつ読み込みたい。
うまくいった理由を知りたい!!
###発生している問題・エラーメッセージ
Perlで、ファイルを1行ごとに読み込むプログラムを作っています。
※ファイルはコマンド実行時に引数として与えます。
関数を呼び出す処理を書いていたところ、以下のエラーメッセージが発生しました。

: No such file or directory at read_lines.pl line 17.

###該当のソースコード

Perl

1&read_lines; 2sub read_lines{ 3 my $file = shift; 4 open(my $fh, '<', $file) or die "$file: $!"; 5 my @lines = <$fh>; 6 foreach my $line (@lines) { 7 print $line; 8 } 9}

###試したこと
「fileが無いよ」と言われていて、もしや「変数のスコープ」の問題かと考えました。
以下のように変数fileを関数の外で宣言した所、問題なくファイルの中身を1行ずつ標準出力することができました。

Perl

1my $file = shift; 2&read_lines; 3sub read_lines{ 4 open(my $fh, '<', $file) or die "$file: $!"; 5 my @lines = <$fh>; 6 foreach my $line (@lines) { 7 print $line; 8 } 9}

成功はしたのですが、なぜうまくいったのか理解できていないので、コメントを頂きたく質問致しました。
宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

上記でお答えは出ていますので別角度から、メインで引数を渡す。

Perl

1&read_lines(shift); 2sub read_lines{ 3 my $file = shift; 4 open(my $fh, '<', $file) or die "$file: $!"; 5 my @lines = <$fh>; 6 foreach my $line (@lines) { 7 print $line; 8 } 9}

投稿2016/10/08 15:13

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

UMA00

2016/10/08 15:25

ありがとうございます!! この書き方は、「mainモジュールのshiftの引数であるコマンドライン引数(読み取るファイル名)を、サブルーチンに渡してサブルーチン内で変数fileに代入する」という処理を行っているのですよね?
A.Ichi

2016/10/08 15:40

そうですね、私は$ARGV[$n]派ですshiftが何回目かよく迷うので。
UMA00

2016/10/09 03:35

2つ以上の引数を扱う場合には、1つ目が$ARGV[0]、2つ目が$ARGV[1]、…とした方がぱっと見て分かりますね。shiftは配列の1番目、次は2番目、次は3番目、…と要素をとってくる関数なんですね。
guest

0

ベストアンサー

問題はshiftの位置です。
引数のないshiftを呼び出した場合、mainモジュールではコマンドラインの引数の配列から取り出され、sub内ではサブルーチンの引数の配列から取り出されるからです。
サブルーチンread_linesに引数が与えられていないので、前者のコードのshiftはundefを返したのです。

投稿2016/10/08 13:49

naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

UMA00

2016/10/08 15:22

ありがとうございます!! 大変わかりやすく、納得致しました。 「何も指定しない場合に、何を引数として取ってくるのか」、というところが理解できていなかったようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問