একটি হ্যাক প্রয়োজন কারণ require(এবং এইভাবে use) উভয়ই ফেরার আগে মডিউলটি সংকলন করে এবং সম্পাদন করে।
একই জন্য যায় eval। evalকোডটি কার্যকর না করে সংকলন করতে ব্যবহার করা যাবে না।
আমি খুঁজে পেয়েছি এমন অন্তত অন্তর্নিহিত সমাধানটি ওভাররাইড করা হবে DB::postponed। সংকলিত প্রয়োজনীয় ফাইলটি মূল্যায়নের আগে এটিকে বলা হয়। দুর্ভাগ্যক্রমে, এটি কেবল তখনই ( perl -d) ডিবাগ করার সময় বলা হয় ।
আর একটি সমাধান হ'ল ফাইলটি পড়ুন, এটি পরিবর্তন করুন এবং পরিবর্তিত ফাইলটি মূল্যায়ন করুন, নিচের মত দারুণ কিছু:
use File::Slurper qw( read_binary );
eval(read_binary("Foo.pm") . <<'__EOS__') or die $@;
package Foo {
no warnings qw( redefine );
sub bar { 7 }
}
__EOS__
%INCউপরেরটি সঠিকভাবে সেট করা নেই , এটি সতর্কতা এবং এর দ্বারা ব্যবহৃত ফাইলের নামটি মিস করে, এটি কল করে না DB::postponed, ইত্যাদি etc. নীচে আরও দৃ solution় সমাধান:
use IO::Unread qw( unread );
use Path::Class qw( dir );
BEGIN {
my $preamble = '
UNITCHECK {
no warnings qw( redefine );
*Foo::bar = sub { 7 };
}
';
my @libs = @INC;
unshift @INC, sub {
my (undef, $fn) = @_;
return undef if $_[1] ne 'Foo.pm';
for my $qfn (map dir($_)->file($fn), @libs) {
open(my $fh, '<', $qfn)
or do {
next if $!{ENOENT};
die $!;
};
unread $fh, "$preamble\n#line 1 $qfn\n";
return $fh;
}
return undef;
};
}
use Foo;
আমি ব্যবহার করেছি UNITCHECK(যা সংকলনের পরে বলা হয় তবে মৃত্যুদন্ড কার্যকর হওয়ার আগে) কারণ আমি unreadপুরো ফাইলটি পড়ার পরিবর্তে ওভাররাইড (ব্যবহার করে ) চাপিয়ে দিয়েছি এবং নতুন সংজ্ঞা সংযোজন করেছি। আপনি যদি এই পদ্ধতির ব্যবহার করতে চান, আপনি ব্যবহার করে ফিরে যেতে একটি ফাইল হ্যান্ডেল পেতে পারেন
open(my $fh_for_perl, '<', \$modified_code);
return $fh_for_perl;
হুক্স উল্লেখ করার জন্য @ গ্রিন্জ থেকে কুদোস @INC।
Foo::barতবেuse Fooএটি সংকলন পর্ব (পূর্বে সেখানে কিছু সংজ্ঞায়িত করা থাকলে পুনরায় সংজ্ঞাকরণ বার) এবং ফু-র রানটাইম পর্ব উভয়ই চালিত করবে। আমি কেবল যে জিনিসটি ভাবতে পারি তা হ'ল গভীরভাবে হ্যাক@INCহুক হ'ল ফু কীভাবে বোঝা যায় তা পরিবর্তন করতে।