ऐसा करने का उचित तरीका यह नहीं है। आप जो कर रहे हैं उसे पूरा करने के लिए कुछ और तरीका ढूंढें। इस तकनीक में वैश्विक चर, वर्ग की सभी समस्याएं हैं। जब तक आप फ़ंक्शन के ठीक से पुनः लिख नहीं लेते, तब तक आप उस कोड के सभी प्रकार को तोड़ सकते हैं जिसे आप कभी भी नहीं जानते थे। और जब आप एक मौजूदा ओवरराइड पर उड़ने में विनम्र हो सकते हैं, तो शायद कोई और नहीं होगा।
ओवरराइडिंग system
विशेष रूप से स्पर्शपूर्ण है क्योंकि इसमें उचित प्रोटोटाइप नहीं है। ऐसा इसलिए है क्योंकि यह प्रोटोटाइप सिस्टम में चीजों को व्यक्त नहीं करता है। इसका मतलब है कि आपका ओवरराइड कुछ चीजें नहीं कर सकता है जो system
कर सकते हैं। अर्थात् ...
system {$program} @args;
यह एक वैध तरीका system
कॉल करने के लिए, हालांकि आप यह करने के लिए exec
डॉक्स पढ़ने की जरूरत है। आप सोच सकते हैं "ओह, ठीक है, मैं बस ऐसा नहीं करूँगा", लेकिन यदि आप जिस मॉड्यूल का उपयोग करते हैं, वह करता है, या इसका उपयोग करने वाला कोई भी मॉड्यूल करता है, तो आप भाग्य से बाहर हैं।
उस ने कहा, विनम्रतापूर्वक किसी भी अन्य कार्य को ओवरराइड करने से थोड़ा अलग है। आपको मौजूदा फ़ंक्शन को फंसाना होगा और सुनिश्चित करें कि आप इसे अपने नए में कॉल करें। चाहे आप इससे पहले या बाद में करते हैं।
आपके कोड में समस्या यह है कि फ़ंक्शन परिभाषित किया गया है या नहीं, यह जांचने का उचित तरीका defined &function
है। एक अपरिभाषित फ़ंक्शन का भी एक कोड रेफरी लेना, हमेशा एक सच्चा कोड रेफरी वापस कर देगा। मुझे यकीन नहीं है कि क्यों, शायद \undef
एक स्केलर रेफरी वापस करेगा। इस कोड रेफ को क्यों कॉल करना mysystem()
को असीमित रूप से रिकर्सिव करने के लिए किसी का अनुमान है।
इसमें एक अतिरिक्त जटिलता है कि आप कोर फ़ंक्शन का संदर्भ नहीं ले सकते हैं। \&CORE::system
आपका मतलब नहीं है। न ही आप इसे प्रतीकात्मक संदर्भ के साथ प्राप्त कर सकते हैं। इसलिए यदि आप CORE::system
या मौजूदा ओवरराइड को कॉल करना चाहते हैं, जिस पर परिभाषित किया गया है, तो आप केवल एक या दूसरे को कोड रेफरी पर असाइन नहीं कर सकते हैं। आपको अपने तर्क को विभाजित करना होगा।
यहां ऐसा करने का एक तरीका है।
package first;
use strict;
use warnings;
sub override_system {
my $after = shift;
my $code;
if(defined &CORE::GLOBAL::system) {
my $original = \&CORE::GLOBAL::system;
$code = sub {
my $exit = $original->(@_);
return $after->($exit, @_);
};
}
else {
$code = sub {
my $exit = CORE::system(@_);
return $after->($exit, @_);
};
}
no warnings 'redefine';
*CORE::GLOBAL::system = $code;
}
sub mysystem {
my($exit, @args) = @_;
print("in first mysystem, got $exit and @args\n");
}
BEGIN { override_system(\&mysystem) }
package main;
system("echo hello world");
ध्यान दें कि मैं mysystem() बदल दिया है केवल एक हुक है कि वास्तविक प्रणाली के बाद चलता है किया जाना है। यह सभी तर्क और निकास कोड प्राप्त करता है, और यह निकास कोड बदल सकता है, लेकिन यह system()
वास्तव में नहीं बदलता है। हुक के पहले/बाद में जोड़ना एकमात्र चीज है जो आप कर सकते हैं यदि आप मौजूदा ओवरराइड का सम्मान करना चाहते हैं। वैसे भी यह थोड़ा सा सुरक्षित है। ओवरराइडिंग सिस्टम की गड़बड़ी अब एक अव्यवस्था में है जो BEGIN को बहुत अव्यवस्थित होने से रोकती है।
आपको अपनी आवश्यकताओं के लिए इसे संशोधित करने में सक्षम होना चाहिए।