myとourの違いが、飲み込めません。
以下、当方の環境とします。
【コード(1) ファイル名は read.pl とする】
#!/bin/perl
use strict;
use warnings;
my @filelist = <abc*.log>;
foreach my $i (0 .. $#filelist){
open(IN, "$filelist[$i]");
my @alltxt = <IN>;
sub f_readlines {
my $export=0;
foreach my $strings(@alltxt){
$export .= $strings;
}
return $export;
}
【コードの説明と前提】
これは、read.plを実行すると、同じディレクトリにある、「abcで始まり .logで終わるファイル」のすべてを引数として、
同じ処理を繰り返すコードです。
実行時のカレントディレクトリには、abc001.log、abc002.log、abc003.logという3つのファイルが存在します。
abc001.log には aaaaaaa という文字列が書き込まれています。
abc002.log には bbbbbbb という文字列が書き込まれています。
abc003.log には ccccccc という文字列が書き込まれています。
【コード(1)の実行結果】
$ ./read.pl
aaaaaaa
aaaaaaa
aaaaaaa
【現状と当方の考え】
このコードの本来の目的は、存在するファイルの数だけ、その中身を順次読みだす、というものです。
ですので、コード(1)の実行結果は
$ ./read.pl
aaaaaaa
bbbbbbb
ccccccc
になってくれないといけないのです。
しかし、
my @alltxt = <IN>;
の行を
our @alltxt = <IN>;
に書き換えると、うまくいきました。
ネットを見ていると、myはスコープの範囲が限定的で、ローカルな変数のようで、
グローバル(どこでも変数として取り出せる)なものが our、というように読み取れます。
foreach の処理の中で宣言した my @alltxt ですから、
ファイルの数だけ、毎回 @alltxt の中身の値は変わるはずです。
それが、変わってくれず、初回に@alltxtに読み込んだ aaaaaaa だけが、ファイルの数だけ
出力されてしまいます。
【質問したいこと】
(1)myを使って代入した変数の中身は、同じスコープ内で作成した関数からは読みだせないのか?
(2)それならば、なぜ初回のaaaaaaaは、読み出せているのか?
以上よろしくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
あ, #1 は完全に勘違いしてた. ということで最初からやり直し.
まず, my を使うと「そこを通るたびに違う変数を作る」と思っていい. つまり, 今の場合 foreach で回す 3つのファイルのそれぞれに対して @alltxt が存在する. それに対して, サブルーチン f_readlines は 1つだけ存在し, その中では「最初の @alltxt」だけがアクセスできる. その結果「初回に@alltxtに読み込んだ aaaaaaa だけが、ファイルの数だけ出力されてしまいます」という結果になっている (2つ目以降では「ファイルから読み込んだ値を保持する @alltxt」と「f_readlines からアクセスする @alltxt」が別個に存在する).
一方 our は「(必要ならグローバルな変数を作って) それを現在のスコープに導入する」という働きになる. だから my の代わりに our を使うと @alltxt は 1つだけ存在し, それをサブルーチン f_readlines がアクセスするので期待通りの動作になる.
ちなみに勘違いのもとは, どうも foreach でまわす変数だけは扱いが違うっぽいところ.
No.1
- 回答日時:
Perl のサブルーチンは基本的にファイルスコープでしか作れない. だから, そのプログラムは
#!/bin/perl
use strict;
use warnings;
my @filelist = <abc*.log>;
sub f_readlines {
my $export=0;
foreach my $strings(@alltxt){
$export .= $strings;
}
return $export;
}
foreach my $i (0 .. $#filelist){
open(IN, "$filelist[$i]");
my @alltxt = <IN>;
# 以下の詳細は不明
と書いたのと同じことになる.
というのが (1) の答え. (2) については完全なプログラムが提示されていないので不明.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- その他(クラウドサービス・オンラインストレージ) Google ColabでGoogleドライブのサブフォルダにファイルを生成する方法 1 2022/10/31 17:37
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Visual Basic(VBA) 【VBA】写真の縦横比を変えずに貼り付ける 5 2023/06/13 11:42
- Perl perlをバージョンアップしたら、今まで正常に動いていたプログラムが、エラーになってしまった 3 2022/10/05 15:44
- その他(開発・運用・管理) 【至急】.htaccessによるディレクトリ単位でのリダイレクト 2 2023/08/10 13:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
JavaでCSVファイルを高速に読む...
-
VBAでCSVファイルの特定行を書...
-
形態素解析の解析内容を各品詞...
-
CSVが可変長の場合の検索方法
-
vNoteのBODY部の取得(長めです)
-
openした後、closeしないでプロ...
-
VBAでCSVファイルを途中行まで...
-
VB6.0でDB接続する際に切断時の...
-
プログラミング(流れ図とコー...
-
拡張子 ”log” と ” dat” の違い
-
VBAコードを張り付け後のエクセ...
-
バッチファイルの作り方(CSV→...
-
batファイルでrenameができませ...
-
close()で例外が投げられる理由
-
vba dir の相対パス
-
MATLABのm-fileについて
-
文字列をカウントする方法
-
至急お願いします。C言語で.img...
-
一定時間が経過したフォルダの削除
-
画像アップロード機能を追加し...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでCSVファイルの特定行を書...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
VBAでCSVファイルを途中行まで...
-
VBAで巨大なファイルの途中から...
-
ReadLineでの読み出し行を指定する
-
JavaでCSVファイルを高速に読む...
-
MATLAB グローバル変数の宣言
-
エクセルVBA コードが同じでも...
-
Perlの変数に文字数制限(容量...
-
perlで、後ろの行を読んで、前...
-
C言語でのファイルのデータ更...
-
2つのCSVファイルをマッチング
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
perlで容量の大きいCSVファイル...
-
1ファイルずつ読み込みたい
-
VBScriptでファイル保存先のデ...
-
perl で googleAPIを呼び出す...
-
C#でCSVファイルを逐一更新したい
おすすめ情報