2009-03-16 20 views
10

मैं दो चीजें करना चाहता हूं:मैं पर्ल फ़ंक्शंस में निर्मित कैसे परिभाषित करूं?

उत्पादन कोड में, मैं ओपन कमांड को फिर से परिभाषित करना चाहता हूं ताकि मुझे स्वचालित फ़ाइल लॉगिंग जोड़ने में सक्षम बनाया जा सके। मैं डेटा प्रसंस्करण अनुप्रयोगों/प्रवाहों पर काम करता हूं और इसके हिस्से के रूप में, उपयोगकर्ता के लिए यह जानना महत्वपूर्ण है कि वास्तव में कौन सी फाइलें संसाधित की जा रही हैं। यदि वे किसी फ़ाइल के पुराने संस्करण का उपयोग कर रहे हैं, तो उन्हें ढूंढने के लिए एक तरीका है संसाधित होने वाली फ़ाइलों की सूची के माध्यम से पढ़ना।

मैं सिर्फ एक नया उप बना सकता हूं जो यह लॉगिंग करता है और फ़ाइल सूचक देता है और मेरे कोड में खुले स्थान पर इसका उपयोग करता है।

यह वास्तव में अच्छा होगा अगर मैं केवल खुले को फिर से परिभाषित कर सकता हूं और इस व्यवहार से पूर्व-मौजूदा कोड लाभ प्राप्त कर सकता हूं। क्या मैं यह कर सकता हूं?

डीबग कोड में, मैं लिखित आउटपुट के साथ टिप्पणियां सम्मिलित करने के लिए printf कमांड को फिर से परिभाषित करना चाहता हूं जो इंगित करता है कि कौन सी कोड उस पंक्ति को उत्पन्न करती है। दोबारा, मेरे पास एक सब है जो वैकल्पिक रूप से ऐसा करेगा, लेकिन मेरे मौजूदा कोड को परिवर्तित करना कठिन है।

उत्तर

9

खुला के लिए: यह मेरे लिए काम करता है।

use 5.010; 
use strict; 
use warnings; 
use subs 'open'; 
use Symbol qw<geniosym>; 

sub open (*$;@) { 
    say "Opening $_[-1]"; 
    my ($symb_arg) = @_; 
    my $symb; 
    if (defined $symb_arg) { 
     no strict; 
     my $caller = caller(); 
     $symb = \*{$symb_arg}; 
    } 
    else { 
     $_[0] = geniosym; 
    } 
    given (scalar @_) { 
     when (2) { return CORE::open($symb // $_[0], $_[1]); } 
     when (3) { return CORE::open($symb // $_[0], $_[1], $_[2]); } 
    } 
    return $symb; 
} 

open PERL4_FH, '<', 'D:\temp\TMP24FB.sql'; 
open my $lex_fh, '<', 'D:\temp\TMP24FB.sql'; 

Printf के लिए: आप इस प्रश्न की जाँच की थी? ->How can I hook into Perl’s print?

+0

nb की तरह व्यवहार नहीं कर रहा है केवल वर्तमान नामस्थान को प्रभावित करता है। – chaos

+0

ब्रेक 1-Arg खुला :) – ysth

+0

गैर-खोल पाइप भी खोलता है: मेरा $ एफएच खोलें, "| -", "ls", "-l" –

13

यदि कोई कोर सबराउटिन प्रोटोटाइप * है तो इसे प्रतिस्थापित किया जा सकता है। वर्तमान नामस्थान में फ़ंक्शन को प्रतिस्थापित करना काफी आसान है।

#!/usr/bin/perl 

use strict; 
use warnings; 

use subs 'chdir'; 

sub chdir(;$) { 
    my $dir = shift; 
    $dir = $ENV{HOME} unless defined $dir; 
    print "changing dir to $dir\n"; 
    CORE::chdir $dir; 
} 

chdir("/tmp"); 
chdir; 

आप सभी मॉड्यूल के लिए समारोह ओवरराइड करने के लिए चाहते हैं और साथ ही आप docs पढ़ सकते हैं।

* पर्ल 5.10 में प्रत्येक फ़ंक्शन का परीक्षण करने के लिए कोड यहां दिया गया है (यह पहले के संस्करणों पर भी काम करेगा)। नोट, कुछ फ़ंक्शंस को ओवरराइड किया जा सकता है कि यह प्रोग्राम आपको बताएगा कि आप नहीं हो सकते हैं, लेकिन ओवरराइड फ़ंक्शन मूल फ़ंक्शन के समान व्यवहार नहीं करेगा।

perldoc -f प्रोटोटाइप

से

builtin overridable नहीं है, तो (जैसे qw के रूप में //) या अपने तर्कों पर्याप्त रूप से एक प्रोटोटाइप द्वारा व्यक्त नहीं किया जा सकता है, तो (जैसे प्रणाली के रूप में), प्रोटोटाइप() undef देता है, क्योंकि अंतर्निहित वास्तव में एक पर्ल समारोह

#!/usr/bin/perl 

use strict; 
use warnings; 

for my $func (map { split } <DATA>) { 
    my $proto; 
    #skip functions not in this version of Perl 
    next unless eval { $proto = prototype "CORE::$func"; 1 }; 
    if ($proto) { 
     print "$func has a prototype of $proto\n"; 
    } else { 
     print "$func cannot be overridden\n"; 
    } 
} 

__DATA__ 
abs   accept   alarm   atan2   bind   
binmode  bless   break   caller   chdir 
chmod  chomp   chop   chown   chr 
chroot  close   closedir  connect   continue 
cos   crypt   dbmclose  defined   delete 
die   do    dump   each    endgrent 
endhostent endnetent  endprotoent endpwent   endservent 
eof   eval   exec   exists   exit 
exp   fcntl   fileno   flock   fork 
format  formline  getc   getgrent   getgrgid 
getgrnam  gethostbyaddr gethostbyname gethostent  getlogin 
getnetbyaddr getnetbyhost getnetent  getpeername  getpgrp 
getppid  getpriority getprotobyname getprotobynumber getprotoent 
getpwent  getpwnam  getpwuid  getservbyname getservbyport 
getservent getsockname getsockopt  glob    gmtime 
goto   grep   hex   import   index 
int   ioctl   join   keys    kill 
last   lc    lcfirst  length   link 
listen  local   localtime  lock    log 
lstat  m    map   mkdir   msgctl 
msgget  msgrcv   msgsnd   my    next 
no   oct   open   opendir   ord 
our   pack   package  pipe    pop 
pos   print   printf   prototype  push 
q   qq    qr    quotemeta  qw 
qx   rand   read   readdir   readline 
readlink  readpipe  recv   redo    ref 
rename  require  reset   return   reverse 
rewinddir rindex   rmdir   s    say 
scalar  seek   seekdir  select   semctl 
semget  semop   send   setgrent   sethostent 
setnetent setpgrp  setpriority setprotoent  setpwent 
setservent setsockopt  shift   shmctl   shmget 
shmread  shmwrite  shutdown  sin    sleep 
socket  socketpair  sort   splice   split 
sprintf  sqrt   srand   stat    state 
study  sub   substr   symlink   syscall 
sysopen  sysread  sysseek  system   syswrite 
tell   telldir  tie   tied    time 
times  tr    truncate  uc    ucfirst 
umask  undef   unlink   unpack   unshift 
untie  use   utime   values   vec 
wait   waitpid  wantarray  warn    write 
y   -r    -w    -x    -o 
-R   -W    -X    -O    -e 
-z   -s    -f    -d    -l 
-p   -S    -b    -c    -t 
-u   -g    -k    -T    -B 
-M   -A    -C 
+0

उसने मुझे बताया कि चोप्स को ओवरराइड नहीं किया जा सका, लेकिन यह वैसे भी काम करता था। – Axeman

+0

चंप फ़ंक्शन सुरक्षित रूप से ओवरराइड नहीं किया जा सकता है। डिफ़ॉल्ट परिवर्तनीय व्यवहार को बल देने का कोई तरीका नहीं है। इससे कोड पर असर पड़ेगा जो इसे काम करने की अपेक्षा करता है। –

+0

नोट: http://search.cpan.org/dist/perl-5.10.0/pod/perl5100delta।पॉड # ___ प्रोटोटाइप महत्वपूर्ण है यदि आपका कोड लेक्सिकल $ _ – ysth

संबंधित मुद्दे