编程C,C ++,Java,PHP,Ruby,图灵,VB
计算机科学加拿大 
编程C,C ++,Java,PHP,Ruby,图灵,VB  

用户名:   Password: 
 登记登记   
 WIP - Perl旋风
指数 -> 一般编程
查看上一个主题 可打印的版本下载主题订阅本主题私人信息刷新页面 查看下一个主题
作者 信息
WTD.




邮政发布: 2006年8月12日星期六下午6:36  帖子主题:WIP - Perl旋风

Perl旋风

数据类型

Perl有四个基本数据类型,以及与这些基本数据类型。

最基本的是标量。标量是数字或字符串。标量变量以美元符号sigil开头。

代码:
$ foo ="bar";
$ baz = 42;
$ qux = 3.14;


下一个数据类型是数组。 Perl阵列包含Perl标量。数组变量以符号sigil开头。

代码:
@Values =("bar", 42, 3.14);


访问数组的元素很简单。 Perl阵列零索引。

代码:
$ foo = $值[0];


哇哇哇哇哇哇哇哇哇哇哇哇为什么sigil改变?好吧,SIGIL改变了因为一旦我访问了阵列内的标量,就在处理标量时。

接下来我们有另一个有用的数据类型:哈希。哈希存储多个标量,就像数组一样,但它们不会使用整数作为索引。哈希变量以百分比符号sigil开头。

代码:
%math_stuff =("pi" => 3.14);


然后我们可以用一个非常简单的语法来获得它。

代码:
$ pi = $ math_stuff {"pi"};


等等,我说有四个数据类型

还有第四个。目前想知道你如何创建一系列数组?

我想我们可以尝试:

代码:
@ art =(1, 2, (3, 4, 5));


它看起来我们将数组作为数组的元素之一。事实上,我们没有。我们拥有的是令人尊敬的事情。

代码:
@ art =(1, 2, 3, 4, 5);


我们可能会尝试更加绝望:

代码:
@sub_arr =.(3, 4, 5);
@ art =(1, 2, @sub_arr);


但再次,我们留下了同样的结果。

我们需要的是全能的参考。 Perl引用基本上是另一种标量。所以它可以生活在数组内或散列作为单个项目。这是因为它真的是单个项目。这只是一个单一的项目,持有一个标志,指向别的东西。标量变量将相同的美元符号sigil作为标量变量。

我们可以使用反斜杠运算符来获得对标量,数组或哈希的引用。

代码:
@Values =("bar", 42, 3.14);
%math_stuff =("pi" => 3.14);
$ agal_ref = \ @values;
$ math_stuff_ref = \%math_stuff;
@ art =($ value_ref,$ math_stuff_ref);


但那有点乏味,所以让我们简化一下。

代码:
@Values =("bar", 42, 3.14);
%math_stuff =("pi" => 3.14);
@ art =(\ @Values,\%math_stuff);


我们甚至可以通过使用语法来创建匿名阵列和哈希引用来更好。

代码:
@ art =(["bar", 42, 3.14], {"pi" => 3.14});


所以,现在让我们说我们想要获得值42.我们可以以正常方式获得对数组的引用。

代码:
$ arr [0]


但是,但是,我们必须取消引用该阵列。

代码:
@ {$ arr [0]}


然后我们可以以正常方式访问42。

代码:
@ {$ arr [0]} [1]


但这看起来相当乏味,所以我们将使用间接运营商。

代码:
$ arr [0] - >[1]


当然,如果我们希望向其中包含的数组命名,我们仍然必须使用显式解密。

同样,如果我们想要PI的值,或者至少我们的令人难以置信的近似值。

代码:
%{$ arr [1]} {"pi"}


或者:

代码:
$ arr [1] - >{"pi"}


子程序

到目前为止,所有这些代码都刚刚独自一起来。让我们开始给它名称并将其组织成子程序。

代码:
子hello_world {
   print "Hello world\n";
}


这是一个非常简单的子程序。它甚至没有参加论点。让我们做一个。只有一个问题。 Perl不提供子程序标题中的任何位置,以向参数/参数提供名称。

相反,所有参数都作为特殊数组中的项目传递。

代码:
子你好{
   #args位于@_数组中
   $name = $_[0];
   
   print "Hello $name\n";
}


但是有几个成语来处理争论。 Shift子程序将从数组中取出第一个元素并返回它。这对于处理争论非常有用。

代码:
子你好{
   #args位于@_数组中
   $name = shift @_;
   
   print "Hello $name\n";
}


如果没有指定数组,甚至更好地,在此情况下,Shift在此案例中执行正确的事情。

代码:
子你好{
   $name = shift;
   
   print "Hello $name\n";
}


我们将在一段时间内看到的其他成语。

范围

只是一个重要的问题。让我们展开该样本。

代码:
$ name =."hello";

子你好{
   $name = shift;
   
   print "Hello $name\n";
}

打印"$name\n";
你好 "world";
打印"$name\n";


这里的问题是输出是:

代码:
你好
你好,世界
世界


“Hello”子程序修改了外部变量中的值。

要解决此问题,我们将使我们的变量与“我”表示明确的范围。

代码:
我的$名称="hello";

子你好{
   my $name = shift;
   
   print "Hello $name\n";
}

打印"$name\n";
你好 "world";
打印"$name\n";


输出现在:

代码:
你好
你好,世界
你好


就像我们期望的那样。



但是当我们想要组织子程序时呢?好吧,那就是套餐进来的地方。

我们可以在一个源文件中拥有不同的包。默认包是“main”。让我们将以前的子程序移动到“问候”包中。

代码:
套餐问候;

子你好{
   my $name = shift;
   
   print "Hello $name\n";
}

包装主要;

问候::hello "world";


虽然更有用的是,当我们将包分开到自己的文件中作为一个模块时,所以可以用许多不同的程序重用。

在文件致辞中.pm:

代码:
套餐问候;

子你好{
   my $name = shift;
   
   print "Hello $name\n";
}

1;


尾随人告诉Perl解释器模块返回true。如果它不这样做,程序将在尝试使用此模块时终止。

如果这位于Perl @ inc阵列中的一向列出,我们可以在我们的程序中轻松使用它。

代码:
使用问候;

问候::hello "world";


把东西从一个包中拿出来

这一切都很好,很好,我们已经在我们可以重用的模块中打包了我们的子程序,但如果我们不想一直在模块名称将其添加到哪个模块?

那么,我们可以使用出口商模块。

代码:
套餐问候;

使用出口商;

@isa = qw.(Exporter);
@Export = QW.(&hello);

子你好{
   my $name = shift;

   print "Hello $name\n";
}

1;


现在我们可以写:

代码:
使用问候;

你好 "world";


“Hello”子程序(子例程有一个ampersand sigil)已从问候模块自动导出到我们的程序中。唯一的是......这里真的有很多控制。如果我不想导出子程序怎么办?

嗯,那么我将在该模块中指定,如果用户希望,可以导出Hello。

代码:
套餐问候;

使用出口商;

@isa = qw.(Exporter);
@export_ok = qw.(&hello);

子你好{
   my $name = shift;

   print "Hello $name\n";
}

1;


现在达到与以前的版本相同:

代码:
使用问候qw.(&hello);

你好 "world";


应该注意的是,“qw”构造占据了一个字符串,将其拆分在空格上,并创建一个字符串数组。非常方便的小写代码。

对象怎么样?

所有其他酷孩子都可以玩对象。

代码:
班级名称
   def initialize(first, last)
     @first,@last =首先,最后
   end
   
   def full_name
      "#{@first} #{@last}"
   end
结尾


那么为什么不perl?

好吧,这是愚蠢的,当然perl可以做对象。例如,我们将以Name.pm置于以下代码。

代码:
包裹名字;

使用严格;
使用警告;

次新{
   my ($班级,$ first,$最后) = @_;
   my $self = {first => $first, last => $last};
   bless $self, $class
}

sub full_name {
   my $self = shift;
   "$self->{first} $self->{last}"
}

1;


由于我们不想导出方法,我们在此处不使用出口商。

你应该注意到一些新的东西。我们正在使用严格和警告模块。这些强制对变量和打印警告消息的更严格控制。因此,我们现在无法逃脱未指定变量的范围。

接下来你会注意到:

代码:
my ($班级,$ first,$最后) = @_;


在这里,我们从参数阵列中的列表上下文中的变量分配。这将为该数组中的前三个值分配给变量,并忽略其余部分。

第一个参数将是实际的类名。旁边只是提供给构造函数的参数。

我们接下来将我们的$ SELF变量创建为哈希参考。然后我们可以将此哈希引用作为名称对象。你会注意到没有半冒号。在Perl中,半冒号仅作为分隔符,而不是终端存在。由于子程序的闭合支架用于此目的,因此不需要半冒号。此外,子程序中的最后一个表达式将自动返回。由于保佑的自我争夺祝福,我们不需要明确退回$自我,尽管我们可以。

在full_name方法中,第一个参数是self对象。然后,我们可以访问该哈希中的数据。我们使用字符串插值将该数据包含在一个字符串中,该字符串从子程序返回使用前面删除的字符串。只有双引号中的字符串只会进行插值。

然后我们可以在程序中使用此类。

代码:
使用严格;
使用警告;

使用名称;

我的$ n = name->new('Bob', 'Smith');

打印$n->full_name . "\n";


这里的点运算符用于连接字符串。

过载

哇,这里的最后一行代码解释了。为什么我们不能只使用字符串插值?

好吧,这是因为方法调用,例如使用的方法,没有在字符串插值中进行评估。

但在Ruby中,我们可以简单地覆盖到自动称为的方法。在Perl中,我们使用过载模块。

代码:
包裹名字;

使用严格;
使用警告;

使用超载""' => sub {
   my $self = shift;
   $self->full_name
};

次新{
   my ($班级,$ first,$最后) = @_;
   my $self = {first => $first, last => $last};
   bless $self, $class
}

sub full_name {
   my $self = shift;
   "$self->{first} $self->{last}"
}

1;


在这里,我们将参数列表传递给过载。是的,我们已经使用箭头运算符与哈希一起使用,但您看到的...哈希真的与阵列非常相似。箭头可以用逗号替换,它仍然可以工作。然而,这种方式看起来很好。

这里的其他重要事项是我们创建了匿名子程序参考。相反,我们可以使用对实际子程序的引用。

代码:
包裹名字;

使用严格;
使用警告;

使用超载""' => \&full_name;

次新{
   my ($班级,$ first,$最后) = @_;
   my $self = {first => $first, last => $last};
   bless $self, $class
}

sub full_name {
   my $self = shift;
   "$self->{first} $self->{last}"
}

1;


遗产

代码:
包拼写;

使用严格;
使用警告;

使用名称;

我们的@isa = qw(Name);

使用超载""' => \&full_name;

次新{
   my ($课程,$标题,$第一,$持续) = @_;
   my $self = Name->new($first, $last);
   $self->{title} = $title;
   bless $self, $class
}

sub full_name {
   my $self = shift;
   $self->{title} . ' ' . Name::full_name($self)
}

1;


这里唯一真正的新事物正在建立继承。通过使用“我们的”而不是“我的”,我们已经使阵列在包之外可见。

通常,我们只需将它们的名称保存.pm和ormyname.pm在我们的Include路径中的某个位置并使用它完成。但是......如果我们想以利用Perl的能力的方式调用铭文类别,该怎么办?也许是名字::正式,也许?

嗯,然后在与name.pm的同一目录中,我们会创建一个名称目录。融入了以下内容,正如正式.PM。

代码:
包裹名字::Formal;

使用严格;
使用警告;

使用名称;

我们的@isa = qw(Name);

使用超载""' => \&full_name;

次新{
   my ($课程,$标题,$第一,$持续) = @_;
   my $self = Name->new($first, $last);
   $self->{title} = $title;
   bless $self, $class
}

sub full_name {
   my $self = shift;
   $self->{title} . ' ' . Name::full_name($self)
}

1;


然后我们可以在一个程序中使用:

代码:
使用名称::Formal;


包括路径

如果我们不能将这些文件放在预定义的包含路径中的某个位置,该文​​件怎么样?我们如何使用它们?

在那个事件中,我们将使用其他包来告诉Perl在哪里看。

代码:
使用lib'/ some / directory';


如果要测试此操作,请简单地打印@ inc阵列。

代码:
使用lib'foo';

打印"\@INC is @INC\n";


让我们已经阅读了一些用户输入!

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印"Your name is? ";
Chomp.(my $name = <STDIN>);

打印"Hello, $name!\n";


首先,我在我的程序顶部添加了一个谢银线。这告诉它是如何运行此脚本的程序。所以现在我可以chmod我的小程序可执行并运行它:

代码:
./hello.pl.


其余的看起来很正常,直到你进入“chomp”。 Chomp子程序从字符串的末尾删除空格。我可以写这一点:

代码:
我的$名称=<STDIN>;
Chomp. $name;


但第一个版本具有相同的效果,并将其全部放入一行中。

然后我们只需使用字符串插值来打印问候语。

争论

但是,不要询问名称,让我们让用户通过名称以作为命令行参数迎接。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

我的$名称=$ARGV[0];

打印"Hello, $name!\n";


阵列长度

但是如果保存所有提供的参数的@argv数组是空的,那么怎么了?然后尝试获得第一个元素,将导致宇宙遍布您的漂亮壳。这根本不擅长。

为了避免这种情况,我们需要能够检测到是否存在至少一个参数。我们需要能够找到阵列的长度。

现在,在列表上下文中,数组只是列表。这完美无缺。但是,在标量上下文中,数组是一个整数。整数恰好是数组的长度。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

if (scalar @ARGV >= 1) {
   my $name = $ARGV[0];

   print "Hello, $name!\n";
}


让我们缩短一点。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

if (scalar @ARGV >= 1) {
   print "Hello, $ARGV[0]!\n";
}


现在让我们缩短一个魔法后缀有点更远。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印"Hello, $ARGV[0]!\n" if scalar @ARGV >= 1;


但是,在Perl中,0是假的。任何其他整数都是真的。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印"Hello, $ARGV[0]!\n" if scalar @ARGV;


但我们甚至不必走得那么远。空数组是假的。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印"Hello, $ARGV[0]!\n" if @ARGV;


但如果我们想要有一些“其他”条件,那么Postfix条件并没有多少帮助。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

if (@ARGV) {
   print "Hello, $ARGV[0]!\n";
} 别的 {
   print "请在下次输入名称。\ n";
}


斯德尔

到目前为止,我们刚刚一直印刷给标准输出,这是一个漂亮的文件手柄,但不是我们开箱即用的唯一文件。

让我们从前面的示例中打印错误emssage到标准错误文件手柄。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

if (@ARGV) {
   print "Hello, $ARGV[0]!\n";
} 别的 {
   print STDERR "请在下次输入名称。\ n";
}


是的,它对任何其他FileHandle都同样的方式工作。

问候整个名字

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

我的$ i = 0;

尽管($i <= $#ARGV) {
   print "Hello, $ARGV[$i]!\n";
   $i++;
}


这是这样做的方式。虽然循环不是一个非常复杂的实现目标的手段,但它有效。 $#argv构造检索@argv数组的最后一个索引。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

为了(my $i = 0; $i <= $#ARGV; $i++) {
   print "Hello, $ARGV[$i]!\n";
}


这里没有什么特别复杂的。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

为了(@ARGV) {
   print "Hello, $_!\n";
}


以上表示用于每个循环。我们只是循环对索引的而不是处理索引。每个元素都被分配给$ _变量。我们甚至可以用它作为INVIX控制结构。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印"Hello, $_!\n" for @ARGV;


但这不是一个非常有意义的变量名。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

为了my $name (@ARGV) {
   print "Hello, $name!\n";
}


让我们映射它!

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印for map { "Hello, $_!\n" } @ARGV;


Map将每个元素带到数组中,调用它$ _,并将其更改为其他值,生成新列表。

当我们使用print for no参数时,它将自动打印$ _的值。 postfix中的for循环将调用每个元素$ _。因此,我们得到了预期的行为。

选择性

让我们不要迎接任何名叫拉里的人。不要让拉里偷偷摸摸地使用奇怪的拼写。

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

打印for map {
   "Hello, $_!\n"
grep {
   ! /\b larry \b/ix
@argv;


他们自己的正则表达式自动尝试匹配$ _。感叹号运营商将否定。如果名称不包含“Larry”,则否则返回true。

地图和格雷普:那点了什么?

使用地图和Grep,我们已经采取了多个步骤,并在代码中单独表达它们。这使我们更容易修改道路上的代码。

如果我们在没有这样的工具的情况下这样做:

代码:
#!/ / usr / bin / perl

使用严格;
使用警告;

为了my $name (@ARGV) {
   if ($名称!〜/ \ b larry \ b / ix) {
      print "Hello, $name!\n";
   }
}
赞助
赞助
赞助
赞助
克莱顿




邮政发布: Sun 8月13日,2006年12:53 PM  帖子主题:(没有主题)

W00T好工作WTD,我对霍彻的想法非常感兴趣,更易读,更好的组织工具然后是一个数组
WTD.




邮政发布: Sun 8月13日,2006年12:57 PM  帖子主题:(没有主题)

哈希也存在于其他语言中。 Ruby和Python都有非常好的实现。 Ruby再次调用它们哈希,但Python是指他们作为词典。

如果内存服务,您也可能会看到它们称为“关联阵列”,如PHP和JavaScript中
克莱顿




邮政发布: Sun 8月13日,2006年1:28 PM  帖子主题:(没有主题)

实际上我要问的一件事,是perl中的一种对象,还是是一种模块?
WTD.




邮政发布: Sun 8月13日,2006年1:31 PM  帖子主题:(没有主题)

模块。虽然你也许是关于对象的问题。 眨眼
克莱顿




邮政发布: Sun 8月13日,2006年1:37 PM  帖子主题:(没有主题)

我只是想知道它是什么(我更倾向于认为这是一个模块),虽然我肯定了 非难
八达峰




邮政发布: 2006年8月14日2:49下午2:49  帖子主题:(没有主题)

男人,你只是让我想起了我多么喜欢perl

it was the first language I learned, but I haven't used it in sooo long, its so great for making small programs quickly, and its got an amazing library of modules (http://www.cpan.org), which pretty much makes it easy to do anything! (even make windows gui apps)
WTD.




邮政发布: 2006年8月14日2:51下午2:51  帖子主题:(没有主题)

Perl是我花了很多时间学习的第一语言。
赞助
赞助
赞助
赞助
从上一个显示帖子:   
   指数 -> 一般编程
查看上一个主题 告诉一个朋友可打印的版本下载主题订阅本主题私人信息刷新页面 查看下一个主题

11  [ 8 Posts ]
跳到:   


Style:  
搜索: