এভাবেই উপরে একটি প্রস্তাবনায় বেশি হয় না এটা করতে। আমি বরং একটি বড় পার্ল অ্যাপ্লিকেশনটিতে একটি বাগ খুঁজে পেতে খুব খারাপ সময় কাটিয়েছি। মডিউলগুলির বেশিরভাগের নিজস্ব কনফিগারেশন ফাইল ছিল। সামগ্রিকভাবে কনফিগারেশন ফাইলগুলি পড়তে, আমি পার্লের এই একক লাইনটি ইন্টারনেটে কোথাও পেয়েছি:
# Bad! Don't do that!
my $content = do{local(@ARGV,$/)=$filename;<>};
এটি পূর্বে বর্ণিত হিসাবে লাইন বিভাজকটিকে পুনরায় নিয়োগ দেয়। তবে এটি এসটিডিএনকেও পুনরায় নিয়োগ দেয়।
এটির অন্তত একটি পার্শ্ব প্রতিক্রিয়া ছিল যা পেতে আমার কয়েক ঘন্টা ব্যয় করে: এটি অন্তর্ভুক্ত ফাইল হ্যান্ডেলটি সঠিকভাবে বন্ধ করে না (যেহেতু এটি কল করে না close
)।
উদাহরণস্বরূপ, এটি করা:
use strict;
use warnings;
my $filename = 'some-file.txt';
my $content = do{local(@ARGV,$/)=$filename;<>};
my $content2 = do{local(@ARGV,$/)=$filename;<>};
my $content3 = do{local(@ARGV,$/)=$filename;<>};
print "After reading a file 3 times redirecting to STDIN: $.\n";
open (FILE, "<", $filename) or die $!;
print "After opening a file using dedicated file handle: $.\n";
while (<FILE>) {
print "read line: $.\n";
}
print "before close: $.\n";
close FILE;
print "after close: $.\n";
ফলাফল স্বরূপ:
After reading a file 3 times redirecting to STDIN: 3
After opening a file using dedicated file handle: 3
read line: 1
read line: 2
(...)
read line: 46
before close: 46
after close: 0
আশ্চর্যের বিষয়টি হ'ল, $.
প্রতিটি ফাইলের জন্য লাইন কাউন্টারটি এক এক করে বাড়ানো হয়। এটি পুনরায় সেট করা হয়নি, এবং এতে লাইনের সংখ্যা নেই। কমপক্ষে একটি লাইন না পড়া পর্যন্ত অন্য ফাইলটি খোলার সময় এটি শূন্যে পুনরায় সেট করা হয় না। আমার ক্ষেত্রে, আমি এই জাতীয় কিছু করছিলাম:
while($. < $skipLines) {<FILE>};
এই সমস্যার কারণে, শর্তটি মিথ্যা ছিল কারণ লাইন কাউন্টারটি সঠিকভাবে রিসেট করা হয়নি। আমি জানি না এটি কোনও ত্রুটিযুক্ত বা সহজ কোড কিনা ... এছাড়াও close;
ওডার কল করা close STDIN;
কোনও লাভ করে না।
আমি এই অপঠনযোগ্য কোডটি ওপেন, স্ট্রিং কনকেন্টেশন এবং ক্লোজ ব্যবহার করে প্রতিস্থাপন করেছি। তবে ব্র্যাড গিলবার্ট পোস্ট করা সমাধানটিও কাজ করে যেহেতু এটির পরিবর্তে একটি সুস্পষ্ট ফাইল হ্যান্ডেল ব্যবহার করে।
শুরুতে তিনটি লাইন প্রতিস্থাপন করা যেতে পারে:
my $content = do{local $/; open(my $f1, '<', $filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
my $content2 = do{local $/; open(my $f2, '<', $filename) or die $!; my $tmp2 = <$f2>; close $f2 or die $!; $tmp2};
my $content3 = do{local $/; open(my $f3, '<', $filename) or die $!; my $tmp3 = <$f3>; close $f3 or die $!; $tmp3};
যা সঠিকভাবে ফাইল হ্যান্ডেলটি বন্ধ করে দেয়।