我正在阅读代码完成2,其中一个要点是关于创建子程序,即使对于看起来太简单而无法拥有自己的子程序的操作,以及它如何有用.
我知道我可以使用关键字在C和C++中内联函数inline.但我从未想过在Perl中内联子程序的方法.
有没有办法告诉Perl解释器内联子程序调用(或为什么不)?
这在Perl v5.22中得到修复.
Perl v5.18的词法子程序是否有排序?我今天终于有了一个用途,我有一个复杂的排序例程,它依赖于数据结构中的当前位置来查看更深的部分.
这是一个小程序:
use v5.18;
use feature qw(lexical_subs);
no warnings qw(experimental::lexical_subs);
my sub by_numbers { $a <=> $b }
my @sorted = sort by_numbers qw( 4 8 2 3 0 5 7 6 1 9 );
say "sorted: @sorted";
Run Code Online (Sandbox Code Playgroud)
显然sort对此一无所知,因为它仍然在寻找%main::命名子例程:
% perl5.18.2 test.pl
Undefined sort subroutine "main::by_numbers" called at test.pl line 7.
% perl5.20.1 test.pl
Undefined sort subroutine "main::by_numbers" called at test.pl line 7.
Run Code Online (Sandbox Code Playgroud)
我有点失望,因为这是rjbs 在perl 5中的词法子例程中使用的第一个用例.
这部分并不重要,因为我查看了当前版本的测试而不是v5.18版本. …
考虑这两个用例:
sub test1 {
my $v = 1;
sub test2 { print $v }
# ...
}
Run Code Online (Sandbox Code Playgroud)
和
for (0..3) {
my $foo = $_;
sub test1 { print $foo }
# ...
}
Run Code Online (Sandbox Code Playgroud)
第一个产生Variable will not stay shared警告,而第二个产生警告.似乎在两种情况下都不共享该变量.为什么在第二种情况下没有任何警告?
我试图找出在没有传递参数的情况和参数传递为0的情况下在Perl中区分的最佳方法,因为它们对我来说意味着不同的东西.
(通常我喜欢歧义,但在这种情况下我生成SQL所以我想用NULL替换未定义的args,但将0保留为0.)
所以这是含糊不清的:
sub mysub {
my $arg1 = shift;
if ($arg1){
print "arg1 could have been 0 or it could have not been passed.";
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我最好的解决方案......但我认为这有点难看.我想知道你是否可以想到一个更清洁的方式或者这对你来说是否合适:
sub mysub {
my $arg1 = (defined shift) || "NULL";
if ($arg1 ne "NULL"){
print "arg1 came in as a defined value.";
}
else {
print "arg1 came in as an undefined value (or we were passed the string 'NULL')";
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个脚本和一个像这样的包:
# file: sortscript.pl
use strict;
use warnings;
use SortPackage;
my @arrays = ([1,"array1"],[10,"array3"],[4,"array2"]);
print "Using sort outside package\n";
foreach (sort SortPackage::simplesort @arrays){
print $_->[1],"\n";
}
print "\nUsing sort in same package\n";
SortPackage::sort_from_same_package(@arrays);
Run Code Online (Sandbox Code Playgroud)
-
# file: SortPackage.pm
use strict;
use warnings;
package SortPackage;
sub simplesort{
return ($a->[0] <=> $b->[0]);
}
sub sort_from_same_package{
my @arrs = @_;
foreach (sort simplesort @arrs){
print $_->[1],"\n";
}
}
1;
Run Code Online (Sandbox Code Playgroud)
运行脚本会生成输出:
$ perl sortscript.pl
Using sort outside package
Use of uninitialized value in numeric comparison …Run Code Online (Sandbox Code Playgroud) 我需要能够在Mojolicious :: Lite应用程序中编写和调用我自己的子例程.但是,这样做的直观方式似乎并不奏效.我通过电子邮件发送了一位比我对此问题有更多Mojolicious经验的同事,他给我发了以下代码:
#!/usr/bin/env perl
use Mojolicious::Lite;
# Documentation browser under "/perldoc"
plugin 'PODRenderer';
get '/' => sub {
my $self = shift;
$self->render('index');
};
sub factorial {
my $n = shift;
return $n ? $n * factorial($n - 1) : 1;
}
app->start;
__DATA__
@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!
Five factorial: <%= main::factorial(5) %>
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>
Run Code Online (Sandbox Code Playgroud)
但是当我运行它时,它告诉我当我调用一个未定义的子程序时:
未定义的子程序&main :: …
使用原型,您可以创建一个接受代码块作为其第一个参数的子例程:
sub example (&) {
my $code_ref = shift;
$code_ref->();
}
example { print "Hello\n" };
Run Code Online (Sandbox Code Playgroud)
我怎么能做同样的事情,但有多个代码块?我想使用代码块,而不是变量或sub { ... }.
这不起作用:
sub example2 (&&) {
my $code_ref = shift;
my $code_ref2 = shift;
$code_ref->();
$code_ref2->();
}
example2 { print "One\n" } { print "Hello\n" };
Run Code Online (Sandbox Code Playgroud)
它给出了这个错误:
Not enough arguments for main::example2
Run Code Online (Sandbox Code Playgroud) 我正在编写一些代码,其中我使用子例程作为左值和右值来读取和写入数据库值.问题是,我希望它根据它是用作左值还是右值来做出不同的反应.
我希望子程序在用作左值时写入数据库,并在数据库用作右值时从数据库中读取.
例:
# Write some data
$database->record_name($subscript) = $value;
# Read some data
my $value = $database->record_name($subscript);
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一方法就是找到一种方法让子程序识别它是用作左值还是左值,并对每种情况做出不同的反应.
有没有办法做到这一点?
对于Perl子例程,如果传递0参数,我可以使用4个表单来调用它.但是如果传递一个或多个参数,有一个我不能使用的表单,请看下面:
sub name
{
print "hello\n";
}
# 4 forms to call
name;
&name;
name();
&name();
sub aname
{
print "@_\n";
}
aname "arg1", "arg2";
#&aname "arg1", "arg2"; # syntax error
aname("arg1", "arg2");
&aname("arg1", "arg2");
Run Code Online (Sandbox Code Playgroud)
错误输出是
String found where operator expected at tmp1.pl line 16, near "&aname "arg1""
(Missing operator before "arg1"?)
syntax error at tmp1.pl line 16, near "&aname "arg1""
Execution of tmp1.pl aborted due to compilation errors.
Run Code Online (Sandbox Code Playgroud)
有人可以从编译器的角度解释错误输出吗?我不明白为什么抱怨缺少操作员.
谢谢
有没有办法对形式参数进行赋值?
就像是:
sub myfunc($n) {
$n = $n + 5;
return $n;
}
Run Code Online (Sandbox Code Playgroud)
或者,我是否必须创建一个新变量并为其分配$ n的值?
subroutine ×10
perl ×9
arguments ×1
function ×1
inline ×1
invocation ×1
lexical ×1
lvalue ×1
mojolicious ×1
package ×1
parameters ×1
perl5.18 ×1
perl6 ×1
rvalue ×1
shift ×1
sorting ×1
syntax ×1
undefined ×1
variables ×1