簡體   English   中英

為什么我在 Perl 代碼中收到“過早調用以檢查原型”警告?

[英]Why am I getting “called too early to check prototype” warnings in my Perl code?

我有一個像這樣的 Perl 文件:

use strict;
f1();

sub f3()
{ f2(); }

sub f1()
{}
sub f2()
{}

簡而言之, f1在定義之前被調用。 因此,Perl 發出警告:“f1 調用過早,無法檢查原型”。 但是f2的情況也是如此,唯一的區別是它是從另一個子程序內部調用的。 它不會對f2發出警告。 為什么?

解決此問題的最佳方法是什么?

  1. 在調用之前聲明子程序
  2. 像這樣調用 sub: &f1();

您可以通過不使用原型來完全避免這個問題:

use strict;

f1();

sub f3 { f2() }

sub f1 {}
sub f2 {}

不要使用原型,除非你知道為什么要使用它們:

當然,這一切都非常強大,應該適度使用,以使世界變得更美好。

只需從您的子程序定義中刪除 ()。 當你用 () 定義時,Perl 認為這些是原型,你必須在使用它之前定義你的原型。

試試這個:

use strict;
f1();

sub f3
{ f2(); }

sub f1
{}
sub f2
{}

在 Perl 中定義函數時,不應使用括號。 當你這樣做時,你會得到這個錯誤。 這是錯誤的:

sub DoSomthing(){
   #do what ever...
}

這是要走的路:

sub DoSomthing{
   #do what ever...
}

沒有括號。

有關更詳細的說明,請參閱 Gabor Szabo 的 Perl Maven 頁面,了解 Perl 中的子例程和函數。 https://perlmaven.com/subroutines-and-functions-in-perl

f3()調用f2()缺少警告似乎是一個錯誤。

use strict;
use warnings;

f1();

sub f1 {
    my @a = qw(a b c);
    f2(@a);
}

sub f2(\@) { print $_[0] }

這將打印“a”。 如果您預先聲明f2()或交換子例程定義的順序,它將打印“ARRAY(0x182c054)”。

至於如何解決,那就看情況了。 我的偏好(按順序)是:

  1. 從子程序定義中刪除原型。 Perl 的原型並沒有像大多數人期望的那樣做。 它們實際上僅用於聲明像內置函數一樣的子程序。 除非你想擴展 Perl 的語法,否則不要使用它們。
  2. 在使用子程序之前預先聲明它們。 這讓 Perl 在遇到任何調用之前就知道原型。
  3. 重新排序代碼,以便子例程定義出現在任何調用之前。
  4. 使用&foo()符號調用子程序以繞過原型檢查。

如果你打算用括號調用它,你為什么還要使用原型?

sub f1(){ ... }

f1();

我唯一會使用空原型的時間是用於我想像常量一樣工作的子程序。

sub PI(){ 3.14159 }

print 'I like ', PI, ", don't you?\n";

我實際上建議不要使用 Perl 5 原型,除非您希望子程序的行為與其他情況不同。

sub rad2deg($){ ... }

say '6.2831 radians is equal to ', rad2deg 6.2831, " degrees, of course.\n";

在此示例中,如果沒有原型,則必須使用括號。 否則它會得到一個額外的參數,最后一個字符串永遠不會被打印出來。

你可以像C語言一樣先聲明它。

sub test($);

test("xx");

sub test($) {
   # do something
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM