একটি হ্যাক প্রয়োজন কারণ 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
হুক হ'ল ফু কীভাবে বোঝা যায় তা পরিবর্তন করতে।