2010-09-09 23 views
13

Phần Overriding Built-in Functions của tài liệu perlsub cung cấpCông cụ xây dựng Perl nào không thể ghi đè trong CORE :: GLOBAL?

Có một phương pháp thứ hai đó là đôi khi được áp dụng khi bạn muốn ghi đè lên một built-in ở khắp mọi nơi, không phân biệt ranh giới không gian tên. Điều này đạt được bằng cách nhập một phụ vào không gian tên đặc biệt CORE::GLOBAL::.

và sau đó đưa ra một vài ví dụ. Cuối cùng, tuy nhiên, là

Cuối cùng, một số được xây dựng-in (ví dụ exists hoặc grep) có thể không được ghi đè.

Danh sách đầy đủ là gì?

+0

Tôi rất vui vì bạn đã hỏi điều này vì tôi sắp sửa tự hỏi mình vì tôi phải viết về điều này cho một cuốn sách. :) –

+0

@brian d foy Tôi sẽ gửi hóa đơn của bạn cho tôi. –

+0

Và tôi sẽ thanh toán bằng phiếu thưởng bia tại một số sự kiện của Perl. :) Tôi sẽ cố gắng làm điều này bằng vũ lực và chỉ thấy nơi Perl phàn nàn.Tôi vẫn có thể làm điều đó. –

Trả lời

14

Bất kỳ giá trị nào âm trong toke.c đều có thể bị ghi đè; tất cả những người khác có thể không. Bạn có thể xem mã nguồn here.

Ví dụ, chúng ta hãy nhìn vào waitpid trên đường dây 10.396:

case 'w': 
     if (name[1] == 'a' && 
      name[2] == 'i' && 
      name[3] == 't' && 
      name[4] == 'p' && 
      name[5] == 'i' && 
      name[6] == 'd') 
     {          /* waitpid */ 
     return -KEY_waitpid; 
     } 

Kể từ waitpid là tiêu cực, nó có thể được ghi đè. Làm thế nào về grep?

 case 'r': 
      if (name[2] == 'e' && 
       name[3] == 'p') 
      {         /* grep  */ 
      return KEY_grep; 
      } 

Đó là tích cực, vì vậy không thể ghi đè. Điều đó có nghĩa rằng các từ khóa sau đây không thể được ghi đè:

chop, defined, delete, do, dump, each, else, elsif, eval, exists, for, foreach, format, glob, goto, grep, if, keys, last, local, m, map, my, next, no, package, pop, pos, print, printf, prototype, push, q, qq, qw, qx, redo, return, s, scalar, shift, sort, splice, split, study, sub, tie, tied, tr, undef, unless, unshift, untie, until, use, while, y

+1

Liên kết trong OP chứa một ví dụ cụ thể về chế nhạo 'glob'. – mob

+3

Ví dụ đó làm điều đó bằng cách xuất khẩu một biểu tượng 'glob' cho gói gọi, không thay thế một biểu tượng trong' CORE :: GLOBAL :: ' – friedo

+0

Phải có thêm một số phép thuật:' chop' và 'splice' có thể được mô phỏng. Tôi nghĩ rằng 'shift',' unshift', 'push' và' pop' cũng có thể. – mob

5

Hàm prototype sẽ cho bạn biết liệu bạn có thể ghi đè lên một hàm CORE:: hay không.

Đây là một hack cùng nhau cố gắng để có được tất cả các chức năng mà không cần phải gõ họ:

#!/usr/bin/perl 

use strict; 
use warnings; 

open my $fh, "-|", "perldoc", "-u", "perlfunc" or die $!; 
my %seen; 
while (<$fh>) { 
    next unless my ($func) = /=item ([a-z]\w+)/; 
    next if $seen{$func}++; 

    my $prototype = prototype "CORE::$func"; 

    print "$func is ", defined $prototype ? "overiddable with $prototype " : 
     "not overiddable", "\n"; 
} 
+3

Có thêm ma thuật cho phép 'do',' require' và 'glob' bị ghi đè. Xem 'perlsub' cho những gì (nếu không phải là như thế nào và tại sao). – mob

1

Các readline(HANDLE) chức năng (và tương đương <HANDLE> I/O điều hành) có thể được chế giễu, nhưng hành vi của nó tự động -gắn đến $_ khi được sử dụng như

while (<HANDLE>) { ... # equivalent to while (defined($_=readline(HANDLE))) 

không thể. Xem chú thích của hobbs tại How can I still get automatic assignment to '$_' with a mocked 'readline' function?. Điều này có nghĩa là mã như

while (<>) {  # implicitly sets $_ 
    do_something_with($_); 
} 

có thể sẽ bị hỏng nếu bạn xác định lại readline.

Các vấn đề liên quan