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

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

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

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

Q&A

解決済

1回答

1732閲覧

[Perl]クラス内でファイルオープンをしたい

Takahiro310

総合スコア30

Perl

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

0グッド

1クリップ

投稿2017/11/01 02:57

編集2017/11/01 03:07

いつもお世話になっています。
perl初心者です。
うまくいかない部分があったので、ご教授、または参考文献(出来ればWeb閲覧できる資料)の提示を頂けたらと思います。

#目標
CSVを扱いたいので、CSVを扱うためのクラスを定義したい
その中で、あるメソッドでファイルオープンし、違うメソッドでファイルを弄りたい
#問題点
ファイルオープン時に生成される(?)ファイルハンドラを使いまわすことができていない(ように思える)。
#環境
Windows10
perlのバージョン:revision 5 version 24 subversion 2

#詳細
以下のように、コンストラクタ、openメソッド、showメソッド、デストラクタを定義しました。

Csv.pm

perl

1package Csv; 2 3# コンストラクタ 4sub new { 5 my $class = shift; 6 my %param = @_; 7 my $self = bless { 8 # ハッシュに初期値を設定する。 9 FILEPATH => $param{FILEPATH}, 10 PERMISSION => $param{PERMISSION} 11 }, $class 12 return $self; 13} 14 15sub open_file { 16 print "Start Sub : open_file\n"; 17 $self = shift; 18 open(my $fh, ($self->{PERMISSION} . " " . $self->{FILEPATH})) or die "Can't open file $file:$!"; 19 $self->{FILEHANDLE} = $fh; 20 while (<$fh>) { 21 chomp; 22 print $_ . "\n"; 23 } 24 print "End Sub : open_file\n"; 25} 26 27sub show { 28 print "Start Sub : show\n"; 29 $self = shift; 30 my $fh = $self->{FILEHANDLE}; 31 while (<$fh>) { 32 chomp; 33 print $_ . "\n"; 34 } 35 print "End Sub : show\n"; 36} 37 38sub DESTROY { 39 print "Start Sub : DESTROY\n"; 40 my $self = shift; 41 close($self->{FILEHANDLE}) or die("Failed closing the file."); 42 print "End Sub : DESTROY\n"; 43} 441; 45

このクラスを以下のように呼び出します
sample.pl

perl

1use strict; 2use warnings; 3use utf8; 4use open ":utf8"; 5 6require "Csv.pm"; 7my $obj = Csv->new( 8 FILEPATH=>'C:\Users\SOMEFOLDER\sample.csv', 9 PERMISSION=>'+<' 10 ); 11 12$obj->open_file(); 13$obj->show(); 14

実行結果は以下のようになりました(CSVの内容はsample.csvと合っています)

Start Sub : open_file
"A", "1"
"B", "2"
"C", "3"
End Sub : open_file
Start Sub : show
End Sub : show
Start Sub : DESTROY
End Sub : DESTROY

ご覧の通り、open_file内ではCSVの内容が表示されていますが、show内では表示されていません。
ファイルハンドラについては、こちらのサイト様を参考にし、色々試してみたものの結局うまくいきませんでした。

どうか、お力をお貸しいただければと思います。

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

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

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

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

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

guest

回答1

0

ベストアンサー

最初のopen_fileでデータファイルを最後まで読み切ってしまっています。次にshowにおいて同じファイルハンドルを使ってファイルを読もうとしています。ところが、すでに最後まで読み切っているので、何も読み取られず、表示されません。

私が同様の関数を作るとすれば、$self->{FILEHANDLE}でfhを共有するなんてややこしいことをせず、一つのsubの中でopen-read-closeまで完結させてしまいますね。

しかし、CSVの処理が目的なら、いちいち自前のモジュールを作るなどという手間をかけるより、Text::CSV_XSという既存のライブラリを使ったほうが良いでしょう。

投稿2017/11/01 04:01

KojiDoi

総合スコア13671

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

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

Takahiro310

2017/11/01 05:48

ファイルハンドルは使い捨てみたいな感じなんですね。 clone関数使ってコピーしても使いまわしはできませんでした。 既存のライブラリあったんですね! 少し探してみたんですけど、見つからなかったので自前で作ることにしましたが、あるならこっち使うことにします 助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問