電子書籍の厳選無料作品が豊富!

お世話になります。

現在、perlの勉強中です。
状況は mac osx 10.6.6です。
使用参考書は「perl言語プログラミングレッスン[入門編]」です。
CGIは関係なしで行っております。

open関数について参考書を読みながら、
勉強をしているのですが、openでファイルをオープンするときについてなのですが、
参考書上では、「関数openは、指定されたファイル名を持つファイルをハードディスクから探し出し、オープンしようと試みます」と言う説明があるのですが、
今現在、試している文例では、特定の場所にファイルがあるときでないと、
オープンしてくれません。

文例は

[test.pl]

use strict;
use warnings;

my $filename = 'file.txt';
open(FILE, $filename) or die "$filename: $!";
while (my $line = <FILE>){
$line =~ s/ /_/g;
print $line;
}
close(FILE);

という形で、ファイルの " " (スペース)を抜き出して
"_" (アンダースコア)に置き換えるという設問です。

ただ、現況は                 
/Users/(myname)/Documents/test/test.pl #(myname)は私の名前のフォルダです。
にあるコードをターミナル上で実行すると、
/Users/(myname)/file.txt
に配置しているときしか、読み込んでくれません。

そこから、ファイルを移動させてしまうと、
読み込んでくれないのです。

そこで、ご質問ですが、

「関数openは、指定されたファイル名を持つファイルをハードディスクから探し出し、オープンしようと試みます」
と参考書に記載がありましたが、実際には探し出しはしてくれないのでしょうか?
それとも、自分のパソコン、コードに問題があるのでしょうか?

自分が指定した場所にあるファイルをオープンするには
どのようにすればよいでしょうか?

ターミナルで指示するのか、それともコードに加えるべきか、
ご指示くださいませ。

また、詳しい方がおられましたら、
お答えいただければと思います。

それでは失礼します。

A 回答 (3件)

> 関数openが1カ所のディレクトリしか探さないという動作をすることが問題なのです。



問題ではなく、正しい動作です。
その参考書の書き方(『ハードディスクから探し出し』)が誤解を与えているかもしれません。
「openは『指定したファイルを』開こうと試みる」とした方が正確でしょう。
探したりしません。
指定したものが有るか無いかです。
指定した所に無いからといって、似たものや別の場所にあるものを、勝手に開いたりはしません。

その指定のルールとして
・ファイル名だけなら、カレントディレクトリにある同ファイル名のもの
・相対パスで指定されていたら、カレントディレクトリを起点として相対パスを辿る
・絶対パスで指定されたら、ルートディレクトリ(/)から辿る
ということになっています。
ここで、どこにも「ホームディレクトリ」や「実行ファイルのあるディレクトリ」という言葉が出てこない事に注意してください。

> /Users/(myname)/Documents/test/test.pl #(myname)は私の名前のフォルダです。
> にあるコードをターミナル上で実行すると、
> /Users/(myname)/file.txt
> に配置しているときしか、読み込んでくれません。

というのは
・スクリプトではファイル名だけしか指定していない→「カレントディレクトリにあるファイル」ルールが適用される。
・ターミナルを起動したままでcdコマンドでカレントディレクトリを移動しないままに /Users/(myname)/Documents/test/test.pl などと実行している → ターミナル起動時のディレクトリ(/Users/(myname))がカレントディレクトリなので、/Users/(myname)/file.txtを指定したことになる
ということだと思います。

例えば、ここで
cd Documents
としてから /Users/(myname)/Documents/test/test.pl としてみてください。今度は /Users/(myname)/file.txt は読み込まないはずです。cdコマンドでカレントディレクトリを /Users/(myname)/Documents へ移動したことで、 file.txtは /Users/(myname)/Documents/file.txt を指すようになります。


このあたりの概念は、ウィンドウでのGUI操作ばかりやってきた方には理解しずらいところはあるかもしれません。
    • good
    • 0
この回答へのお礼

ありがとう御座います!カレントディレクトリの概念と、UNIXのコマンドなど少し覚えた所、自分の質問している事が明後日の方向を向いている事に気付きました。
また、何かありましたらお願いいたします。

お礼日時:2011/03/08 20:25

はずしていたらごめんなさい



実行させているディレクトリの位置を確認してみてはいかがでしょうか

ターミナルからPerlのスクリプトを実行する場合に、
ホームディレクトリ(/Users/ユーザ名)から
コマンド:
「perl Documents/test/test.pl」
等していませんか?

ターミナルで実行している場合、
現在いる場所がカレントディレクトリになります。

上記のようなコマンドで実行した場合、
スクリプトのカレントディレクトリが「Users/ユーザ名/」になってしまい、
そのカレントディレクトリの階層にファイルが存在しないと、
ファイルが開けません。


現在のディレクトリ位置を見るには、pwdを使うとわかります。
あとは、cdで移動してください。
    • good
    • 0
この回答へのお礼

ありがとう御座います。
perlと一緒にUNIXの勉強も始めた所、
おっしゃってることが理解できるようになりました。

プログラムの勉強するには参考書もそうですが、
皆さんに聞いたりするのも大事ですよね!
ありがとうございます!

お礼日時:2011/03/08 20:21

「関数openは、指定されたファイル名を持つファイルをハードディスクから探し出し、オープンしようと試みます」


というのは、ハードディスクにあるすべてのファイルから指定されたファイル名をサーチするということではありません(というか、説明が不適切ですね)。
プログラムにはプログラムを実行する時点での「カレントディレクトリ」という概念があり、そこにあるファイルしか基本的には見にいかないのです。
「/Users/(myname)/file.txt」にあるときは、Perlのスクリプトも「/Users/(myname)」で処理を行っていると思います。そこが、カレントディレクトリです。
そこ以外にあるファイルを読み書き使用する場合は明示的に場所を指定するする必要があります。
方法は二つ
(1)相対パス
「./subdirectory/file.txt」のように指定します。「.」がカレントディレクトリでそこを基準にしてどこにファイルがあるかを指定するやり方です。
(2)絶対パス
「/home/何ちゃら/file.txt」のように「/」から始まる指定の仕方です。

> ターミナルで指示するのか、それともコードに加えるべきか、

場合によると思います。が、コマンドラインでファイル名を指定できるようにしておいたほうが融通が利く場面が多いかなと。

この回答への補足

ご回答ありがとうございます。

ただ、現状は上記で述べているように

/Users/(myname)/Documents/test/test.pl 
にあるコードをターミナル上で実行すると、
/Users/(myname)/file.txt
に配置しているときしか、読み込んでくれません。

と、
関数openが
1カ所のディレクトリしか探さないという動作をすることが問題なのです。
ちなみに、test.pl を

/Users/(myname)/Documents/test/test.pl 以外に
/Users/(myname)/Documents/test/check/test.pl や
/Users/(myname)/Documents/check/test.pl や
/Users/(myname)/test.pl みたいに配置を変えたとしても、
(カレントディレクトリを変えると表現するのでしょうか?)

関数openは 

/Users/(myname)/file.txt

にfile.txtを配置しているときしか、
file.txtを読み込んでくれないのです。

これは異常でしょうか?
また異常でしたら直し方はありますでしょうか?
ご回答いただければと思います。

補足日時:2011/02/16 18:06
    • good
    • 0
この回答へのお礼

カレントディレクトリの概念とUNIXコマンドのcdとpwdを覚えた所、解決しました。
ありがとう御座いました!

お礼日時:2011/03/08 20:23

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