2010-10-27 39 views
7

Khi nhìn qua một số mã tôi đã kết thúc, tôi đi qua dòng này:Gọi một chương trình con trong OOP Perl

my @files = My::Module::DB::raw_info->search_like(customer_handle => $config->{client}, feed => $config->{site}, arrival =>"$date") 

Tôi biết rằng điều này trả về một mảng từ một gói phần mềm được gọi là My::Module::DB::raw_info.

Điều tôi không chắc chắn (và tôi chỉ đang học OOP), là những gì ->search_like đề cập đến.

Tôi không thấy rằng như là một biến hoặc là một chương trình con trong My::Module::DB::raw_info

Bất kỳ gợi ý sẽ được đánh giá cao. Tôi chỉ mới bắt đầu học những thứ này. Nó giống như tắm trong lửa. (Tôi biết tôi sẽ hạnh phúc hơn sau này) Yikes!

Trả lời

5

Nguyên nhân có thể gây ra câu hỏi hóc búa của bạn là My :: Module :: DB mở rộng một số lớp khác. Hãy tìm một khối dọc theo dòng của

use parent Some::Module; 

hoặc

BEGIN { extends Some::Module } 

gần đầu của tôi/Module/DB.pm

Edit: Theo một số bình luận được cách hữu ích chỉ ra dưới đây , có một số cách để phân lớp một lớp Perl, nhưng đây có lẽ là cách phổ biến nhất. (Có thể.)

+3

cũng "sử dụng cơ sở ..." – Arkadiy

+0

"mở rộng" là một điều Moose. =). –

+0

không sử dụng nền tảng; _; , sử dụng cha mẹ! –

8

Điều này có thể do phương pháp được kế thừa từ một lớp cơ sở. Tuy nhiên, trong các tình huống cực kỳ kỳ lạ, nó cũng có thể được tiêm vào không gian tên của mô-đun động mà khó có thể hình dung được.

Bạn có thể tìm thấy phụ của bạn bằng cách tìm kiếm bạo lực hoặc bằng cách tìm ra lớp cơ sở của một mô-đun (và có thể cao hơn chuỗi thừa kế) và chỉ tìm kiếm mã lớp cơ sở. Tôi sẽ hiển thị như thế nào để làm cả hai:


tìm kiếm lực lượng Brute: Đây có lẽ là giải pháp đơn giản nhất trong những trường hợp phức tạp kể từ khi tiểu có thể đã được tiêm vào không gian tên của mô-đun tự động bởi mô-đun không tổ tiên và việc tìm kiếm mô-đun tổ tiên không dễ dàng 100% do nhiều cách xác định thừa kế có thể đã được sử dụng (sử dụng cơ sở, sử dụng phụ huynh, công cụ Moose, công cụ AUTOLOADED)

Đầu tiên, tìm hiểu các mô-đun nào khác được tải bằng My :: Mô-đun

perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC' 

này sẽ in ra vị trí của tất cả những mô-đun

Sau đó, tìm kiếm định nghĩa phụ ở tất cả các mã đó (sau đây phải được tất cả một dòng, tôi chia nó lên để có thể đọc thành 2 dòng):

grep search_like 
    `perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC'` 

Nếu đây trả về quá nhiều kết quả, thay đổi grep để

grep "sub search_like" 
    `perl -e 'use My::Module::DB::raw_info; print "$INC{$_}\n" foreach keys %INC'` 

này sẽ tìm thấy bạn định nghĩa trong bất cứ mô-đun của bạn :: Module :: DB :: raw_info thừa hưởng fro m mà không thực sự phân tích mã mô-đun cho kế thừa.


Inheritance:

Tìm hiểu mẹ của mô-đun sử dụng ISA như sau:

perl -e 'use My::Module::DB::raw_info; print "@My::Module::DB::raw_info::ISA\n";' 

Để làm rõ, điều này chỉ làm việc cho module "cổ điển thừa hưởng" sử dụng @ISA, công cụ không Moose . Nó cũng không hoạt động nếu thường trình được gọi bằng cách sử dụng AutoLoader hoặc được tiêm vào bảng biểu tượng động mà có thể xảy ra trong bất kỳ mã nào, không nhất thiết phải trong mã cha.

+0

:: ISA sẽ không giúp đỡ nếu A) được bắt đầu bởi một nhà xuất khẩu B) nó được bắt đầu bởi một vai trò Moose C) subs ở bất kỳ cấp nào trong cây thừa kế. –

+0

@Kent - chính xác. Đó là lý do tại sao tôi nói rõ ràng "nó COULD cũng được tiêm vào không gian tên của mô-đun động mà khó hơn nhiều để tìm ra." Và được cung cấp - như phương pháp đầu tiên - grep force brute của codebase. Tại sao downvote? – DVK

+0

Không downvote từ tôi =). Mặc dù, được cấp, tôi không thấy rằng =). Tôi nhớ lại có một cách để chọc vào một tiểu đơn vị để xem nó đến từ đâu, nhưng nó hơi gỉ. –

1

Phương pháp có thể được xác định trong các siêu lớp của My::Module::DB::raw_info. Chèn dòng này trước khi gọi tới search_like:

print @My::Module::DB::raw_info::ISA; 

Bây giờ, hãy xem các lớp này.

Nếu điều này không làm việc, bạn có thể sử dụng Devel::Peek 's Dump() để xem nơi chương trình con đến từ:

use Devel::Peek; 
Dump(\&search_like); 

Hãy tìm GVGV::GV part trong đầu ra.

+1

:: ISA sẽ không trợ giúp nếu A) được bắt vít bởi một nhà xuất khẩu B) của nó bắt vít bởi một vai trò Moose C) bất cứ điều gì khác mà tiêm subs tại bất kỳ cấp độ trong cây thừa kế –

+1

& search_like có thể không hoạt động như bạn nghĩ, có thể bạn sẽ cần 'Dump (My :: Module :: DB -> có thể ('raw_info')) '(giả định tất nhiên, raw_info không phải là (horrors) AUTOLOAD và được thực hiện sai) –

1

Có lẽ đó là một số phương pháp được kế thừa. Đọc một chút về Perl inheritance, tìm một số bài tập cho @ISA trong định nghĩa mô-đun của bạn.

+1

:: ISA chỉ hữu ích nếu nó là thừa kế gây ra nó tồn tại.Biên dịch phụ thời gian biên dịch (Gia đình xuất khẩu, vai trò, v.v.) sẽ không hiển thị. –

1

Trong câu trả lời cho "Điều tôi không chắc chắn, và tôi chỉ học OOP (nhờ nhà phát triển của chúng tôi bị sa thải), là" -> search_like "đề cập đến.", Search_like là một phương pháp của class raw_info nhận các cặp giá trị tên như các tham số đầu vào của nó (Perl Cookbook section 10.7).

FYI, cuốn sách khác tôi thấy rất hữu ích là Programming Perl.

+0

Tôi vừa mới mở được cuốn sách nấu ăn Perl Cookbook và tôi đánh giá cao việc bạn cung cấp điều này ..... JW –

2

Bạn có thể sử dụng mô-đun Devel::Peek lõi để xem dữ liệu nội bộ được lưu trữ trong tham chiếu chương trình con.

Để lấy tham chiếu chương trình con từ phương thức OO, bạn sử dụng phương thức ->can(...) của tất cả các đối tượng.

my $code_ref = My::Module::DB::raw_info->can('search_like'); 

và sau đó bạn có thể in ra các thông tin:

use Devel::Peek 'Dump'; 

Dump($code_ref); 

Theo Devel::Peek docs 's, bạn sẽ nhận được một cái gì đó như thế này:

Một tham chiếu đến một chương trình con trông như thế này :

SV = RV(0x798ec) 
     REFCNT = 1 
     FLAGS = (TEMP,ROK) 
     RV = 0x1d453c 
    SV = PVCV(0x1c768c) 
     REFCNT = 2 
     FLAGS =() 
     IV = 0 
     NV = 0 
     COMP_STASH = 0x31068 "main" 
     START = 0xb20e0 
     ROOT = 0xbece0 
     XSUB = 0x0 
     XSUBANY = 0 
     GVGV::GV = 0x1d44e8 "MY" :: "top_targets" 
     FILE = "(eval 5)" 
     DEPTH = 0 
     PADLIST = 0x1c9338 

Điều này cho thấy rằng

  • chương trình con không phải là XSUB (vì START và ROOT khác 0 và XSUB bằng 0);
  • rằng nó được biên dịch trong gói chính;
  • dưới tên MY :: top_targets;
  • bên trong một eval thứ 5 trong chương trình;
  • hiện không được thực hiện (xem DEPTH);
  • không có mẫu thử nghiệm (trường PROTOTYPE bị thiếu).

Vì vậy, COMP_STASH hiển thị cho bạn nơi mã được biên dịch và GVGV :: GV hiển thị cho bạn tên đầy đủ của phụ.

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