这是命令 perlfaq7,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
perlfaq7 - 一般 Perl 语言问题
VERSION
5.021009版
商品描述
本节处理不明确适合以下任何内容的一般 Perl 语言问题
其他部分。
能够 I 得到 a BNF/yacc/RE HPMC胶囊 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 Perl的 语言?
没有 BNF,但您可以在 perly.y 中的 yacc 语法中摸索
如果您特别勇敢,请分发源代码。 语法依赖非常聪明
标记代码,所以准备好冒险进入 toke.c。
用 Chaim Frenkel 的话来说:“Perl 的语法不能简化为 BNF。
解析 perl 分布在 yacc、词法分析器、烟雾和镜像之间。”
什么是 旨在 所有 这些 $@%&* 标点 迹象 和 形成一种 do I 知道 ,尤其是 至 使用 他们?
它们是类型说明符,详见 perldata:
$ 用于标量值(数字、字符串或引用)
@ 用于数组
% 用于散列(关联数组)
& 用于子程序(又名函数、过程、方法)
* 对于该符号名称的所有类型。 在第 4 版中,您像这样使用它们
指针,但在现代 perls 中,您可以只使用引用。
您可能会遇到一些其他符号,但实际上并非如此
类型说明符:
<> 用于从文件句柄输入记录。
\ 引用某物。
注意是 也不 文件的类型说明符或句柄的名称。 这是
应用于句柄 FILE 的“<>”运算符。 它读取一行(好吧,记录——见“$/”
perlvar) 来自标量上下文中的句柄 FILE,或 所有 列表上下文中的行。 什么时候
对文件执行打开、关闭或除“<>”之外的任何其他操作,甚至在说话时
关于手柄,做 而不去 使用括号。 这些是正确的:“eof(FH)”、“seek(FH, 0, 2)”
和“从标准输入复制到文件”。
Do I 始终不曾 它们在许多情况下都能提供类似的结果。 至 报价 my 字符串 or 使用 分号 和 逗号?
通常,一个裸字不需要被引用,但在大多数情况下可能应该是(和
必须在“严格使用”下)。 但是一个哈希键由一个简单的单词和左边的
"=>" 运算符的操作数都被视为被引用:
这是这样的
------------- ---------------
$foo{line} $foo{'line'}
酒吧 => 东西 '酒吧' => 东西
块中的最后一个分号是可选的,列表中的最后一个逗号也是可选的。 好作风
(见 perlstyle) 说把它们放进去,除了单行:
如果 ($whoops) { 退出 1 }
我的@nums = (1, 2, 3);
如果($whoops){
退出 1;
}
我的@lines = (
“有贝伦来自寒冷的山”,
“他迷失了在树叶下徘徊”,
);
创新中心 do I 跳过 一些 回报 价值观?
一种方法是将返回值视为一个列表并对其进行索引:
$dir = (getpwnam($user))[7];
另一种方法是使用 undef 作为左侧的元素:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
您还可以使用列表切片来仅选择您需要的元素:
($dev, $ino, $uid, $gid) = (stat($file))[0,1,4,5];
创新中心 do I 暂时 阻止 警告?
如果您运行的是 Perl 5.6.0 或更高版本,则“使用警告”编译指示允许精细控制
产生什么警告。 有关更多详细信息,请参阅 perllexwarn。
{
没有警告; # 暂时关闭警告
$x = $y + $z; # 我知道这些可能是 undef
}
此外,您可以启用和禁用警告类别。 你关掉
您想要忽略的类别,您仍然可以获得其他类别的警告。 看
perllexwarn 以获取完整的详细信息,包括类别名称和层次结构。
{
没有警告“未初始化”;
$x = $y + $z;
}
如果您有旧版本的 Perl,$^W 变量(记录在 perlvar 中)控制
块的运行时警告:
{
本地 $^W = 0; # 暂时关闭警告
$x = $y + $z; # 我知道这些可能是 undef
}
请注意,与所有标点变量一样,您当前不能使用 我的() 在 $^W 上,仅
当地的().
什么是 an 延期?
扩展是一种从 Perl 调用已编译 C 代码的方法。 阅读 perlxstut 很好
了解更多关于扩展的地方。
do Perl的 运营商 它们在许多情况下都能提供类似的结果。 不同 优先权 比 C 运营商?
事实上,他们没有。 Perl 复制的所有 C 运算符在 Perl 中具有相同的优先级
他们在 C 中做。问题在于 C 没有的运算符,尤其是那些函数
为其右侧的所有内容提供列表上下文,例如。 打印、chmod、exec 等。 这样的
函数被称为“列表运算符”,并出现在优先级表中
破费。
一个常见的错误是这样写:
取消链接 $file || 死“混乱”;
这被解释为:
unlink ($file || die "snafu");
为避免此问题,请添加额外的括号或使用超低优先级
“或”运算符:
(取消链接 $file) || 死“混乱”;
取消链接 $file 或死“snafu”;
“英语”运算符(“and”、“or”、“xor”和“not”)故意降低优先级
仅适用于上述情况的列表运算符。
另一个具有惊人优先级的运算符是幂运算。 它甚至更紧密地结合
比一元减号,使“-2**2”产生负四而不是正四。 这是
也是右联想,意思是“2**3**2”是二的九次方,而不是八
平方。
尽管它具有与 C 中相同的优先级,但 Perl 的“?:”运算符产生一个左值。 这个
将 $x 分配给 $if_true 或 $if_false,具体取决于 $maybe 的真实性:
($也许 ? $if_true : $if_false) = $x;
创新中心 do I 声明/创建 a 结构体?
通常,您不会“声明”结构。 只需使用(可能是匿名的)哈希
参考。 有关详细信息,请参阅 perlref 和 perldsc。 下面是一个例子:
$person = {}; # 新的匿名哈希
$person->{AGE} = 24; # 将字段 AGE 设置为 24
$person->{NAME} = "Nat"; # 将字段名称设置为“Nat”
如果您正在寻找更严格的东西,请尝试 perlootut。
创新中心 do I 创建信息图 a 模块?
perlnewmod 是一个很好的起点,如果不这样做,请忽略有关上传到 CPAN 的部分
想让您的模块公开可用。
ExtUtils::ModuleMaker 和 Module::Starter 也是不错的起点。 许多 CPAN 作者
现在使用 Dist::Zilla 尽可能自动化。
有关模块的详细文档可以在以下位置找到:perlmod、perlmodlib、perlmodstyle。
如果您需要包含 C 代码或 C 库接口,请使用 h2xs。 h2xs 将创建
模块分布结构和初始接口文件。 perlxs 和 perlxstut
解释细节。
创新中心 do I 采用 or 采取 超过 a 模块 已经 on CPAN?
请当前的维护者让您成为共同维护者或将模块转移给您。
如果由于某种原因无法联系到作者,请联系 PAUSE 管理员
[email protected] 谁可能会提供帮助,但每个案例都是分开处理的。
· 如果您还没有 Perl 作者上传服务器 (PAUSE) 的登录名,请登录:
<http://pause.perl.org>
· 写给 [email protected] 解释你做了什么来联系当前的维护者。
PAUSE 管理员也会尝试联系维护者。
· 在流量大的网站上发布一条公共信息,宣布您打算采取
在模块上。
· 稍等一会。 PAUSE 管理员不想太快采取行动,以防当前
维护者正在休假。 如果没有对私人通信或
公开帖子,PAUSE 管理员可以将其转给您。
创新中心 do I 创建信息图 a 类?
(由布赖恩 d foy 提供)
在 Perl 中,类只是一个包,方法只是子例程。 Perl没有得到
比这更正式,让您可以按照自己喜欢的方式设置包(即
是,它不会为您设置任何内容)。
另请参阅 perlootut,一个涵盖类创建的教程和 perlobj。
创新中心 能够 I 展示 if a 变量 is 被污染了?
您可以使用 污染() Scalar::Util 模块的函数,可从 CPAN(或
自 5.8.0 版起包含在 Perl 中)。 另请参阅“清洗和检测受污染数据”
在每秒。
什么是 a 关闭?
闭包记录在 perlref 中。
关闭 是一个计算机科学术语,具有精确但难以解释的含义。 通常,
闭包在 Perl 中作为匿名子例程实现,并持久引用
词法变量在它们自己的范围之外。 这些词汇神奇地指的是
定义子程序时存在的变量(深度绑定)。
闭包最常用于编程语言中,您可以在其中获得返回值
一个函数本身就是一个函数,就像在 Perl 中一样。 请注意,某些语言提供
匿名函数,但不能提供适当的闭包:Python 语言,
例如。 有关闭包的更多信息,请查看任何关于函数式的教科书
编程。 Scheme 是一种不仅支持而且鼓励闭包的语言。
这是一个经典的非闭包函数生成函数:
子 add_function_generator {
返回子{ shift() + shift() };
}
我的 $add_sub = add_function_generator();
我的 $sum = $add_sub->(4,5); # $sum 现在是 9。
返回的匿名子程序 添加函数生成器() 从技术上讲不是关闭
因为它不指代它自己范围之外的词法。 使用闭包给你一个
function 模板 有一些自定义插槽留待以后填充。
将此与以下内容进行对比 make_adder() 函数,其中返回匿名
函数包含对该函数范围之外的词法变量的引用
本身。 这样的引用要求 Perl 返回一个正确的闭包,从而锁定 for
始终是创建函数时词法具有的值。
子 make_adder {
我的 $addpiece = shift;
返回子 { shift() + $addpiece };
}
我的 $f1 = 加法器(20);
我的 $f2 = 加法器(555);
现在 "$f1->($n)" 总是 20 加上你传入的任何 $n,而 "$f2->($n)" 总是
555 加上你传入的任何 $n。闭包中的 $addpiece 一直存在。
闭包通常用于不太深奥的目的。 例如,当你想传入
一些代码变成一个函数:
我的 $line;
超时( 30, sub { $line = });
如果要执行的代码已作为字符串传入,则 '$line = ',就会有
没办法假设 暂停() 访问词法变量 $line 的函数
回到其调用者的范围内。
闭包的另一个用途是创建一个变量 私立 到一个命名的子程序,例如
在子创建时初始化的计数器只能从
子内。 这有时与包文件中的 BEGIN 块一起使用,以确保
变量在包的生命周期内不会被干预:
开始 {
我的 $id = 0;
子 next_id { ++$id }
}
这在 perlsub 中有更详细的讨论; 见条目 一贯 私做
变量.
什么是 is 变量 自杀 和 形成一种 能够 I 防止 它?
此问题已在 perl 5.004_05 中修复,因此防止它意味着升级您的版本
珀尔。 ;)
变量自杀是指您(暂时或永久)失去变量的值。 它
是由范围界定引起的 我的() 和 当地的() 与闭包或别名交互
foreach() 迭代器变量和子程序参数。 曾经很容易在不经意间
以这种方式丢失变量的值,但现在要困难得多。 拿这个代码:
我的 $f = 'foo';
子T{
而 ($i++ < 3) { 我的 $f = $f; $f .= "bar"; 打印 $f, "\n" }
}
T;
打印“最后$f\n”;
如果您正在经历可变自杀,子程序中的“我的 $f”不会选择
值为“foo”的 $f 的新副本。 输出显示在子程序中
$f 的值在不应该泄漏时泄漏,如以下输出所示:
foobar
吧台
吧台吧
最后 foo
添加了三次 "bar" 的 $f 应该是一个新的 $f "my $f" 应该创建一个
每次通过循环的新词法变量。 预期的输出是:
foobar
foobar
foobar
最后 foo
创新中心 能够 I 通过/返回 a {功能, 文件句柄, 大批, 哈希, 方法, 正则表达式}?
您需要传递对这些对象的引用。 为此,请参阅 perlsub 中的“通过引用传递”
特定问题,以及 perlref 以获取有关参考资料的信息。
传递变量和函数
常规变量和函数很容易传递:只需传入对
现有或匿名变量或函数:
func(\$some_scalar);
func(\@some_array);
函数([1..10]);
func(\%some_hash);
func( { 这 => 10, 那 => 20 } );
func(\&some_func);
函数(子 { $_[0] ** $_[1] } );
传递文件句柄
从 Perl 5.6 开始,您可以使用标量变量表示文件句柄,您将其视为
任何其他标量。
打开我的 $fh, $filename or die "Cannot open $filename! $!";
功能($fh);
子功能{
我的 $passed_fh = shift;
我的 $line = <$passed_fh>;
}
在 Perl 5.6 之前,您必须使用 *FH 或 "\*FH" 符号。 这些是
“typeglobs”——参见 perldata 中的“Typeglobs and Filehandles”,尤其是“Pass by
有关详细信息,请参阅 perlsub 中的“参考”。
传递正则表达式
这是一个如何传入字符串和正则表达式以使其匹配的示例
反对。 您可以使用“qr//”运算符构建模式:
子比较{
我的 ($val1, $regex) = @_;
我的 $retval = $val1 =~ /$regex/;
返回 $retval;
}
$match = compare("老麦当劳", qr/d.*D/i);
传递方法
要将对象方法传递给子例程,您可以这样做:
call_a_lot(10, $some_obj, "methname")
子 call_a_lot {
我的 ($count, $widget, $trick) = @_;
for (my $i = 0; $i < $count; $i++) {
$widget->$trick();
}
}
或者,您可以使用闭包来捆绑对象、其方法调用和参数:
我的 $whatnot = sub { $some_obj->obfuscate(@args) };
功能($whatnot);
子功能{
我的 $code = shift;
&$代码();
}
你也可以调查 能够() UNIVERSAL 类中的方法(部分
标准 perl 发行版)。
创新中心 do I 创建信息图 a 静止 多变的?
(由布赖恩 d foy 提供)
在 Perl 5.10 中,用“state”声明变量。 “状态”声明创建
在子程序调用之间持续存在的词法变量:
子计数器 { 状态 $count = 1; $count++ }
您可以通过使用超出范围的词法变量来伪造静态变量。 在
在这个例子中,你定义了子程序“counter”,它使用了词法变量
$计数。 由于您将其包装在 BEGIN 块中,因此 $count 是在编译时定义的,但也
在 BEGIN 块的末尾超出范围。 BEGIN 块还确保
子例程及其使用的值是在编译时定义的,因此子例程已准备好
就像任何其他子程序一样使用,您可以将此代码放在与其他子程序相同的位置
程序文本中的子程序(即通常在代码的末尾)。 子程序
“counter”仍然有对数据的引用,并且是您访问该值的唯一方法
(并且每次这样做时,都会增加该值)。 由定义的内存块中的数据
$count 是“计数器”私有的。
开始 {
我的 $count = 1;
子计数器 { $count++ }
}
我的 $start = counter();
.... # 调用 counter() 的代码;
我的 $end = counter();
在前面的示例中,您创建了一个函数私有变量,因为只有一个函数
记住了它的参考。 您可以在变量存在时定义多个函数
作用域,每个函数都可以共享“私有”变量。 这不是真正的“静态”
因为当词法变量在作用域内时,您可以在函数外访问它,并且
甚至创建对它的引用。 在这个例子中,“increment_count”和“return_count”共享
变量。 一个函数增加值,另一个函数简单地返回值。 他们
都可以访问 $count,而且由于它已经超出范围,所以没有其他方法可以访问
访问它。
开始 {
我的 $count = 1;
子 increment_count { $count++ }
子回报计数 { $count }
}
要声明文件私有变量,您仍然使用词法变量。 一个文件也是一个
范围,因此无法从任何其他文件中看到文件中定义的词法变量。
有关详细信息,请参阅 perlsub 中的“持久私有变量”。 的讨论
perlref 中的闭包可能对您有所帮助,即使我们没有在此使用匿名子例程
回答。 有关详细信息,请参阅 perlsub 中的“持久私有变量”。
什么是 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 差异 之间 动态 和 词法 (静止的) 范围界定? 之间 当地的() 和 我的()?
"local($x)" 保存全局变量 $x 的旧值并为其分配一个新值
子程序的持续时间 这 is 可见 in other 功能 被称为 , 这
子程序. 这是在运行时完成的,因此称为动态范围。 当地的() 总是影响
全局变量,也称为包变量或动态变量。
"my($x)" 创建一个仅在当前子程序中可见的新变量。 这是
在编译时完成,因此称为词法或静态范围。 我的() 总是影响
私有变量,也称为词法变量或(不正确的)静态(范围限定的)
变量。
例如:
子可见{
打印 "var 有值 $var\n";
}
子动态{
本地 $var = '本地'; # 仍然全局的新临时值
可见的(); # 变量名为 $var
}
子词汇{
我的 $var = 'private'; # 新的私有变量,$var
可见的(); #(在子作用域之外不可见)
}
$var = '全局';
可见的(); # 打印全局
动态的(); # 打印本地
词法(); # 打印全局
请注意值“private”在任何时候都不会被打印。 那是因为 $var 只有
块中的那个值 词法() 函数,它对被调用者是隐藏的
子程序。
综上所述, 当地的() 不会使您认为是私有的局部变量。 它给出了一个
全局变量一个临时值。 我的() 如果您想要私密,这就是您要找的
变量。
请参阅“私有变量通过 我的()" 在 perlsub 和 "临时值通过 当地的()" 在 perlsub
令人难以忍受的细节。
创新中心 能够 I ACCESS a 动态 变量 而 a 相似地 命名 词法 is in 范围?
如果你知道你的包,你可以明确地提到它,就像在 $Some_Pack::var 中一样。 笔记
符号 $::var 是 而不去 当前包中的动态 $var,而是
一个在“main”包中,就像你写了 $main::var 一样。
使用变量 '$var';
本地 $var = "全局";
我的 $var = "词法";
打印 "词法是 $var\n";
打印 "全局是 $main::var\n";
或者,您可以使用编译器指令 我们的() 将动态变量带入
当前词法范围。
需要 5.006; # our() 在 5.6 之前不存在
使用变量 '$var';
本地 $var = "全局";
我的 $var = "词法";
打印 "词法是 $var\n";
{
我们的 $var;
打印 "全局是 $var\n";
}
什么是 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 差异 之间 深 和 浅 捆绑?
在深度绑定中,匿名子程序中提到的词法变量是相同的
在创建子例程时在范围内。 在浅绑定中,它们是
当子例程执行时,具有相同名称的任何变量恰好在范围内
叫。 Perl 总是使用词法变量的深度绑定(即那些用
我的())。 但是,动态变量(又名全局、局部或包变量)是
有效地浅绑定。 考虑这只是不使用它们的另一个原因。 见
回答“什么是闭包?”。
不 “我的($foo) = <$fh>;" 工作 对?
“my()”和“local()”在“=”的右侧给出列表上下文。 <$fh> 读取
操作,就像许多 Perl 的函数和运算符一样,可以告诉它是哪个上下文
被召唤并表现得恰到好处。 一般来说, 标量() 功能可以提供帮助。 这个
函数对数据本身没有任何作用(与流行的神话相反),而是告诉它
以任何标量方式行事的论点。 如果该函数没有
定义的标量行为,这当然对您没有帮助(例如 种类()).
但是,要在这种特殊情况下强制执行标量上下文,您只需省略
括号:
本地($foo) = <$fh>; # 错误的
本地($foo) = 标量(<$fh>); # 好的
本地 $foo = <$fh>; # 对
无论如何,您可能应该使用词法变量,尽管问题是相同的
这里:
我的($foo) = <$fh>; # 错误的
我的 $foo = <$fh>; # 对
创新中心 do I 重新定义 a 内建的 功能, 操作员, or 方法?
你为什么要这样做? :-)
如果要覆盖预定义的功能,例如 打开(),那么你必须导入
来自不同模块的新定义。 请参阅“覆盖内置函数”
perlsub。
如果要重载 Perl 运算符,例如“+”或“**”,则需要使用
“使用重载”pragma,记录在重载中。
如果您正在谈论隐藏父类中的方法调用,请参阅“覆盖方法
和方法解析”在 perlootut。
什么是 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 差异 之间 调用 a function as &foo 和 富()?
(由布赖恩 d foy 提供)
将子例程作为 &foo 调用且不带括号会忽略“foo”的原型
并将参数列表的当前值@_ 传递给它。 这是一个例子; 酒吧”
子程序调用 &foo,打印其参数列表:
sub foo { print "foo 中的参数是:@_\n"; }
子栏 { &foo; }
酒吧(“a”,“b”,“c”);
当你用参数调用“bar”时,你会看到“foo”得到相同的@_:
foo 中的参数是: abc
调用带有尾括号的子例程,带或不带参数,不使用
当前@_。 更改示例以在调用“foo”更改后放置括号
该程序:
sub foo { print "foo 中的参数是:@_\n"; }
子栏{ &foo(); }
酒吧(“a”,“b”,“c”);
现在输出显示“foo”没有从它的调用者那里得到@_。
foo 中的参数是:
但是,在调用中使用“&”仍然会覆盖“foo”的原型(如果存在):
sub foo ($$$) { print "Args infoo are: @_\n"; }
子栏_1 { &foo; }
sub bar_2 { &foo(); }
子 bar_3 { foo( $_[0], $_[1], $_[2] ); }
# 子 bar_4 { foo(); }
# bar_4 无法编译:“main::foo at ... 的参数不足”
bar_1( "a", "b", "c" );
# foo 中的参数是:abc
bar_2( "a", "b", "c" );
# foo 中的参数是:
bar_3( "a", "b", "c" );
# foo 中的参数是:abc
@_ pass-through 特性的主要用途是编写子程序,其主要工作是
为您调用其他子程序。 有关更多详细信息,请参阅 perlsub。
创新中心 do I 创建信息图 a 开关 or 案件 陈述?
在 Perl 5.10 中,使用 perlsyn 中描述的“given-when”构造:
使用 5.010;
给定 ( $string ) {
when('Fred') { 说“我找到了 Fred!” }
当('巴尼'){说“我找到了巴尼!” }
when( /Bamm-?Bamm/ ) { 说“我找到了 Bamm-Bamm!” }
默认 { 说“我不认识这个名字!” }
};
如果想使用纯 Perl 并与 5.10 之前的 Perl 版本兼容,则
一般的答案是使用“if-elsif-else”:
对于($variable_to_test){
if (/pat1/) { } # 做点什么
elsif (/pat2/) { } # 做别的事情
elsif (/pat3/) { } # 做别的事情
else { } # 默认
}
下面是一个简单的基于模式匹配的开关示例,以某种方式排列,使
它看起来更像是一个 switch 语句。 我们将根据类型做一个多路条件
存储在 $whatchamacallit 中的引用:
开关: for (ref $whatchamacallit) {
/^$/ && 死“不是参考”;
/SCALAR/ && 做 {
打印标量($$ref);
最后一次切换;
};
/阵列/ && 做{
打印数组(@$ref);
最后一次切换;
};
/HASH/ && 做 {
打印哈希(%$ref);
最后一次切换;
};
/CODE/ && 做 {
警告“无法打印函数引用”;
最后一次切换;
};
# 默认
警告“跳过用户定义的类型”;
}
有关这种风格的其他示例,请参阅 perlsyn。
有时你应该改变常量和变量的位置。 例如,
假设您想测试您得到的答案中的哪一个,但在一种情况下-
不敏感的方式,也允许缩写。 您可以使用以下技术,如果
字符串都以不同的字符开头,或者如果您想排列匹配项
一个优先于另一个,因为“发送”在这里优先于“停止”:
chomp($answer = <>);
if ("SEND" =~ /^\Q$answer/i) { print "Action is sent\n" }
elsif ("STOP" =~ /^\Q$answer/i) { print "Action is stop\n" }
elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" }
elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" }
elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" }
一种完全不同的方法是创建函数引用的散列。
我的 %commands = (
“快乐”=> \&快乐,
“悲伤”,=> \&闷闷不乐,
“完成”=> sub { die“再见!” },
“疯了”=> \&愤怒,
);
打印“你好吗?”;
chomp($string = );
如果($commands{$string}){
$commands{$string}->();
} {
打印“没有这样的命令:$string\n”;
}
从 Perl 5.8 开始,源过滤器模块“Switch”也可用于获取 switch
和案例。 现在不鼓励使用它,因为它与本机不完全兼容
Perl 5.10 的开关,因为它是作为源过滤器实现的,所以它不
当涉及复杂的语法时,总是按预期工作。
创新中心 能够 I 捕捉 访问 至 未定义 变量, 功能, or 方法?
perlsub 的“自动加载”中讨论的 AUTOLOAD 方法允许您捕获对
未定义的函数和方法。
当涉及到会在“使用警告”下触发警告的未定义变量时,
您可以将警告升级为错误。
使用警告 FATAL => qw(uninitialized);
不能 a 方法 包括 in Free Introduction 同 文件 be 找到了?
一些可能的原因:您的继承变得混乱,您拼错了方法
名称,或者对象的类型错误。 查看 perlootut 以获取有关任何
以上案例。 您也可以使用“print ref($object)”来找出类 $object 是
祝福进入。
出现问题的另一个可能原因是您使用了间接对象语法(例如,
在 Perl 发现这样的包存在之前,在类名上“找到 Guru "Samy"")。 它是
最明智的做法是在您开始使用它们之前确保您的软件包都已定义,这将
如果您使用“use”语句而不是“require”,请注意。 如果没有,请确保
改用箭头符号(例如,“Guru->find("Samy")”)。 对象表示法在
对象。
请务必阅读有关在 perlmod 中创建模块以及在
perlobj 中的“方法调用”。
创新中心 能够 I 发现 my 当前 or 调用 包?
(由布赖恩 d foy 提供)
要查找您当前所在的包,请使用特殊文字“__PACKAGE__”,如
记录在 perldata 中。 您只能将特殊文字用作单独的标记,因此您
不能像使用变量那样将它们插入字符串中:
我的 $current_package = __PACKAGE__;
print "我在包 $current_package\n";
如果你想找到调用你的代码的包,也许是为了提供更好的诊断
Carp 可以,使用内置的“调用者”:
子 foo {
我的@args = ...;
我的($package,$filename,$line)=调用者;
print "我是从 $package 包中被调用的\n";
);
默认情况下,您的程序在“main”包中启动,因此您将始终处于某个包中。
这与找出一个对象被祝福到的包裹不同,后者可能不会
成为当前包。 为此,请使用 Scalar::Util 中的“blessed”,这是标准的一部分
Perl 5.8 以后的库:
使用 Scalar::Util qw(blessed);
我的 $object_package = 祝福( $object );
大多数时候,你不应该关心一个对象被祝福成什么包,但是,因为
只要它声称从该类继承:
我的 $is_right_class = eval { $object->isa( $package ) }; # 对或错
而且,对于 Perl 5.10 及更高版本,您不必检查继承来查看
对象可以处理一个角色。 为此,您可以使用来自“UNIVERSAL”的“DOES”:
我的 $class_does_it = eval { $object->DOES( $role ) }; # 对或错
您可以安全地将“isa”替换为“DOES”(尽管反之则不然)。
创新中心 能够 I 评论 a 大 阻止 of Perl的 代码?
(由布赖恩 d foy 提供)
注释掉多行 Perl 的快速而肮脏的方法是将那些
带有 Pod 指令的行。 你必须把这些指令放在行的开头
以及 Perl 需要新语句的地方(所以不要在语句中间
“#”注释)。 你用“=cut”结束评论,结束Pod部分:
=豆荚
我的 $object = NotGonnaHappen->new();
被忽略的子();
$wont_be_assigned = 37;
=切割
快速而肮脏的方法仅在您不打算留下注释代码时才有效
在来源。 如果 Pod 解析器出现,您的多行注释将显示在
Pod 翻译。 更好的方法是将它隐藏在 Pod 解析器之外。
“=begin”指令可以为特定目的标记一个部分。 如果 Pod 解析器
不想处理它,它只是忽略它。 用“评论”标记评论。 结束
使用具有相同标签的“=end”进行注释。 你仍然需要“=cut”才能回到 Perl
来自 Pod 评论的代码:
=开始评论
我的 $object = NotGonnaHappen->new();
被忽略的子();
$wont_be_assigned = 37;
=结束评论
=切割
有关 Pod 的更多信息,请查看 perlpod 和 perlpodspec。
创新中心 do I 清除 a 包?
使用此代码,由 Mark-Jason Dominus 提供:
子擦洗包{
没有严格的“参考”;
我的 $pack = shift;
die“不应该删除主包”
如果 $pack eq "" || $pack eq "main";
我的 $stash = *{$pack 。 '::'}{哈希};
我的 $name;
foreach $name (键 %$stash) {
我的 $fullname = $pack 。 '::' 。 $名称;
# 去掉所有有这个名字的东西。
undef $$全名;
undef @$全名;
undef %$全名;
undef &$fullname;
undef *$全名;
}
}
或者,如果您使用的是最新版本的 Perl,则可以使用
符号::delete_package() 函数代替。
创新中心 能够 I 使用 a 变量 as a 变量 名称?
初学者常常认为他们想要一个变量包含一个变量的名称。
$弗雷德= 23;
$varname = "弗雷德";
++$$varname; # $fred 现在 24
这工作 有时,但出于两个原因,这是一个非常糟糕的主意。
第一个原因是这种技术 仅由 运作方式 on 全球化 变量。 这意味着,如果
$fred 是一个词法变量 我的() 在上面的例子中,代码不起作用
完全:您会不小心访问全局并跳过私有词法
共。 全局变量很糟糕,因为它们很容易意外碰撞
一般用于不可扩展和混乱的代码。
在“use strict”pragma 下禁止使用符号引用。 他们不是真的
引用,因此不会被引用计数或垃圾收集。
使用变量来保存另一个变量的名称的另一个原因是一个坏主意
问题往往源于对 Perl 数据结构缺乏了解,
特别是哈希。 通过使用符号引用,您只是在使用包的
符号表哈希(如 %main::)而不是用户定义的哈希。 解决方法是使用
您自己的哈希值或真实参考。
$USER_VARS{"fred"} = 23;
我的 $varname = "fred";
$USER_VARS{$varname}++; # 不是 $$varname++
在那里我们使用 %USER_VARS 哈希而不是符号引用。 有时这
出现在从用户那里读取带有变量引用的字符串并想要扩展
将它们添加到您的 perl 程序变量的值中。 这也是一个坏主意,因为它
将程序可寻址命名空间和用户可寻址命名空间混为一谈。 代替
读取字符串并将其扩展为程序自身变量的实际内容:
$str = '这里面有 $fred 和 $barney';
$str =~ s/(\$\w+)/$1/eeg; # 需要双重评估
最好像 %USER_VARS 一样保留散列并有变量引用
实际上是指该哈希中的条目:
$str =~ s/\$(\w+)/$USER_VARS{$1}/g; # 这里根本没有 /e
这比以前的方法更快、更干净、更安全。 当然,你不需要
使用美元符号。 您可以使用自己的方案来减少混淆,例如括号
百分比符号等
$str = '这里面有 %fred% 和 %barney%';
$str =~s/%(\w+)%/$USER_VARS{$1}/g; # 这里根本没有 /e
人们有时认为他们想要一个变量包含一个名称的另一个原因
变量是他们不知道如何使用哈希构建正确的数据结构。 为了
例如,假设他们想要在他们的程序中使用两个哈希值:%fred 和 %barney,然后
他们想使用另一个标量变量来按名称引用这些变量。
$name = "弗雷德";
$$name{WIFE} = "威尔玛"; # 设置 %fred
$name = "barney";
$$name{WIFE} = "贝蒂"; # 设置 %barney
这仍然是一个象征性的参考,仍然背负着列举的问题
以上。 写成这样会好得多:
$folks{"fred"}{WIFE} = "wilma";
$folks{"barney"}{WIFE} = "betty";
只需使用多级哈希开始。
唯一一次你绝对 必须 使用符号引用是你真正必须的时候
参考符号表。 这可能是因为这是人们无法真正接受的东西
引用,例如格式名称。 这样做对于方法调用也很重要,
因为这些总是通过符号表进行解析。
在这些情况下,你会暂时关闭“严格的'refs'”,这样你就可以玩了
符号表。 例如:
@colors = qw(红蓝绿黄橙紫紫);
为我的 $name (@colors) {
没有严格的“参考”; # 为区块反悔
*$name = sub { " @_ " };
}
所有这些功能(红色的(), 蓝色(), 绿色()等)看起来是分开的,但真正的
闭包中的代码实际上只编译了一次。
所以,有时你可能想使用符号引用来操作符号表
直接地。 这对于格式、句柄和子例程无关紧要,因为它们是
总是全局的——你不能使用 我的() 在他们。 不过对于标量、数组和散列,
通常用于子程序——您可能只想使用硬引用。
什么是 不 “坏的 口译员” 是什么意思?
(由布赖恩 d foy 提供)
“bad interpreter”消息来自shell,而不是perl。 实际消息可能会有所不同
取决于您的平台、外壳和区域设置。
如果你看到“bad interpreter - no such file or directory”,你的 perl 中的第一行
脚本(“shebang”行)不包含 perl(或任何其他程序)的正确路径
能够运行脚本)。 有时当您将脚本从一个移动时会发生这种情况
机器到另一台机器,每台机器都有不同的 perl 路径--/usr/bin/perl 而不是
例如 /usr/local/bin/perl。 也可能表示源机器有CRLF
行终止符和目标机器只有 LF:shell 试图找到
/usr/bin/perl,但不能。
如果您看到“bad interpreter: Permission denied”,则需要使脚本可执行。
在任何一种情况下,您仍然应该能够使用 perl 显式运行脚本:
% perl 脚本.pl
如果您收到类似“perl: command not found”的消息,则表示 perl 不在您的 PATH 中,这可能
也意味着 perl 的位置不是您期望的位置,因此您需要调整您的
社邦线。
Do I 需要 至 重新编译 XS 模块 ,尤其是 那里 is a 更改 in 这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 C 图书馆?
(由亚历克斯·比米什提供)
如果新版本的 C 库与 ABI 兼容(即应用程序二进制接口
兼容)与您要升级的版本,以及共享库版本
没有改变,不需要重新编译。
著者 AND 版权
版权所有 (c) 1997-2013 Tom Christiansen、Nathan Torkington 和其他作者。
版权所有
本文档是免费的; 您可以在相同的条款下重新分发和/或修改它
作为 Perl 本身。
不管它的分布如何,此文件中的所有代码示例都放在
公共领域。 允许并鼓励您在自己的程序中使用此代码
为了您认为合适的乐趣或利润。 给予信用的代码中的一个简单注释是
礼貌但不是必需的。
使用 onworks.net 服务在线使用 perlfaq7
