韩半仙

  博客园  ::  :: 新随笔  ::  :: 订阅 订阅  :: 管理

1. values represent data.

variables contain values:

 $number = 42;

variable    value

 

perl provides several types of values:

integers/

arrays/

strings/

hashes/

scalars/

reference

 

perl used context to determine type.

 

2. the scope of keyword: my

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

my $decimal = 23456;

sub main
{
my $decimal= 12345;
message($decimal);
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

the output will be 12345

otherwise, if we delete the line:  my $decimal= 12345;

and run again, the output will be 23456;

 

or we can input binary , octal, hex, float and etc in the following way:

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

my $decimal = 23456;

sub main
{
my $decimal= 12345;
my $octal = 012345;
my $hex = 0x1ab7;
my $binary = 0b101010101010;
my $float = 1234.567;
my $exp = 12.34e56;

message("decimal is $decimal");
message("octal is $octal");
message("hex is $hex");
message("binary is $binary");
message("float is $float");
message("exp is $exp");
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

the output will be :

decimal is 12345
octal is 5349
hex is 6839
binary is 2730
float is 1234.567
exp is 1.234e+57

 

3. Strings;

we print the string inside the  single quote and double quote;

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my $n = 42;
my $s1 = "this is a string: $n";
my $s2 = 'this is a string: $n';
message($s1);
message($s2);
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

and get the output:

this is a string: 42
this is a string: $n

notice: 双引号和单引号的区别: 双引号可以输出引号里面的变量的引用值, 单引号输出变量名称;

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my $n = 42;
my $s1 = "this is a string: '$n'";
my $s2 = 'this is a string: \'$n\'';
message($s1);
message($s2);
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

注意转义字符: \

 

有时候我们可以用q代替 '', qq 代替 "";

 

注意此时的不一定非要用{ },可以用任何起始截至的符号都可以, 如[]{}()等。

 

4. List

数组,我们可以定义一个数组, 包含任意标量在里面:

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my @array = (1,"two",3,4);
my ($one, $two, $three, $four)=(1,2,3,4);
message(join(":",@array));
message($one);
message($two);
message($three);
message($four);
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

此时的输出为:

1:two:3:4
1
2
3
4

注意此时标量的初始化方法:

my ($one, $two, $three, $four)=(1,2,3,4);

这样可以对于一组标量进行初始化。

 

数组的元素定义是从0开始,

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my @array = (1,"two",3,4);
message($array[1]);
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

注意此时此时用到 $array[1], 这个是由于访问的虽然是数组里面的元素, 而不是数组本身, 所以要用标量的符号;

访问数组元素必须用方括号[];

如果需要返回数组的元素个数,可以有一下方法:

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my @array = (1,"two",3,4);
message("there are ".scalar @array . " elements in the array");
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

此时的输出为:there are 4 elements in the array

 

5. slice.

本代码描述了对于数组元素的访问:

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my @array = (1..10);
message(join(':',@array));
message(join(':',@array[1,4,7]));
message(join(':',@array[0..2,7]));
message(join(':',@array[9,3,5]))
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

此时相应的输出为:

1:2:3:4:5:6:7:8:9:10
2:5:8
1:2:3:8
10:4:6

 

6.hash

下面的例子说明了怎么定义一个hash和访问hash里面的元素:

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

sub main
{
my %hash= ("this"=>"foo","that"=>"bar","other"=>"baz");
message($hash{"that"});
message($hash{"other"});
message($hash{"this"});
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

此时的输出为:

bar
baz
foo

注意: 此时符号:=>可以被逗号 , 完全替代。我们为了代码的阅读方便,还是建议用=>的符号定义hash。

访问hash的时候, 是需要用大括号。

 

我们还可以用一下的方式访问和输出hash的key和value:

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my %hash= ("this"=>"foo","that"=>"bar","other"=>"baz");
message(join(':',values(%hash)));
message(join(':',sort(values(%hash))));
message(join(':',sort(keys(%hash))));
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

运行一次的输出为:

baz:bar:foo
bar:baz:foo
other:that:this

注意此时第一行的输出可能在运行的时候得到的结果不一样,这个是由hash本身的性质决定的。在后面我们用了sort的关键字来对于需要访问的数值进行排序,排序的方式是ASCII表的顺序。

 

看下面的例子,我们对于键值对的匹配输出:

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

sub main
{
my %hash= ("this"=>"foo","that"=>"bar","other"=>"baz");
foreach my $k (sort keys %hash){
my $v = $hash{$k};
message("$k is $v");
}
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

输出为:
other is baz
that is bar
this is foo

我们下面看一个用while 循环的对比例子, 此时我们用到了each关键字:

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

sub main
{
my %hash= ("this"=>"foo","that"=>"bar","other"=>"baz");

while(my($k,$v)=each %hash){
my $v = $hash{$k};
message("$k is $v");
}
message("===================");
foreach my $k (sort keys %hash){
my $v = $hash{$k};
message("$k is $v");
}
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

得到的结果如下所示:

other is baz
that is bar
this is foo
===================
other is baz
that is bar
this is foo

可能我看到的输出还是一样的, 这个是因为hash的元素比较少的缘故, 如下所示,我们现在可以将hash的元素换成系统调用的ENV

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my %hash= %ENV;
while(my($k,$v)=each %hash){
my $v = $hash{$k};
message("$k is $v");
}
message("===================");
foreach my $k (sort keys %hash){
my $v = $hash{$k};
message("$k is $v");
}
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

得到的输出如下所示:

GJS_DEBUG_TOPICS is JS ERROR;JS LOG
XAUTHORITY is /home/oliver/.Xauthority
XDG_CURRENT_DESKTOP is GNOME
UBUNTU_MENUPROXY is libappmenu.so
LC_COLLATE is zh_CN.UTF-8
QT_IM_MODULE is xim
XDG_SEAT_PATH is /org/freedesktop/DisplayManager/Seat0
GNOME_KEYRING_CONTROL is /tmp/keyring-IFwe6P
MANDATORY_PATH is /usr/share/gconf/gnome-shell.mandatory.path
GIO_LAUNCHED_DESKTOP_FILE is /usr/share/applications/eclipse.desktop
SSH_AUTH_SOCK is /tmp/keyring-IFwe6P/ssh
PWD is /home/oliver
USER is oliver
LANG is zh_CN.UTF-8
LC_MESSAGES is zh_CN.UTF-8
XDG_CONFIG_DIRS is /etc/xdg/xdg-gnome-shell:/etc/xdg
LOGNAME is oliver
GNOME_DESKTOP_SESSION_ID is this-is-deprecated
XDG_SESSION_COOKIE is d96aad65fd743b76159d1e0900000007-1324698243.576851-1280198017
XDG_SESSION_PATH is /org/freedesktop/DisplayManager/Session1
PATH is /usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
GTK_MODULES is canberra-gtk-module:canberra-gtk-module
GIO_LAUNCHED_DESKTOP_FILE_PID is 15919
XMODIFIERS is @im=ibus
HOME is /home/oliver
DBUS_SESSION_BUS_ADDRESS is unix:abstract=/tmp/dbus-EICx1DlHFb,guid=5f69a46a6a5ae16b8faa144400000416
SSH_AGENT_PID is 2866
GNOME_KEYRING_PID is 2785
LANGUAGE is zh_CN:zh
GJS_DEBUG_OUTPUT is stderr
LD_LIBRARY_PATH is /usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:
DISPLAY is :0
GTK_IM_MODULE is xim
GDMSESSION is gnome-shell
DEFAULTS_PATH is /usr/share/gconf/gnome-shell.default.path
LC_CTYPE is zh_CN.UTF-8
USERNAME is oliver
DESKTOP_SESSION is gnome-shell
XDG_DATA_DIRS is /usr/share/gnome-shell:/usr/share/gnome:/usr/local/share/:/usr/share/
SHELL is /bin/bash
GPG_AGENT_INFO is /tmp/keyring-IFwe6P/gpg:0:1
SESSION_MANAGER is local/oliver-Computer:@/tmp/.ICE-unix/2796,unix/oliver-Computer:/tmp/.ICE-unix/2796
===================
DBUS_SESSION_BUS_ADDRESS is unix:abstract=/tmp/dbus-EICx1DlHFb,guid=5f69a46a6a5ae16b8faa144400000416
DEFAULTS_PATH is /usr/share/gconf/gnome-shell.default.path
DESKTOP_SESSION is gnome-shell
DISPLAY is :0
GDMSESSION is gnome-shell
GIO_LAUNCHED_DESKTOP_FILE is /usr/share/applications/eclipse.desktop
GIO_LAUNCHED_DESKTOP_FILE_PID is 15919
GJS_DEBUG_OUTPUT is stderr
GJS_DEBUG_TOPICS is JS ERROR;JS LOG
GNOME_DESKTOP_SESSION_ID is this-is-deprecated
GNOME_KEYRING_CONTROL is /tmp/keyring-IFwe6P
GNOME_KEYRING_PID is 2785
GPG_AGENT_INFO is /tmp/keyring-IFwe6P/gpg:0:1
GTK_IM_MODULE is xim
GTK_MODULES is canberra-gtk-module:canberra-gtk-module
HOME is /home/oliver
LANG is zh_CN.UTF-8
LANGUAGE is zh_CN:zh
LC_COLLATE is zh_CN.UTF-8
LC_CTYPE is zh_CN.UTF-8
LC_MESSAGES is zh_CN.UTF-8
LD_LIBRARY_PATH is /usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:/usr/lib/jvm/java-6-openjdk/jre/lib/i386:
LOGNAME is oliver
MANDATORY_PATH is /usr/share/gconf/gnome-shell.mandatory.path
PATH is /usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
PWD is /home/oliver
QT_IM_MODULE is xim
SESSION_MANAGER is local/oliver-Computer:@/tmp/.ICE-unix/2796,unix/oliver-Computer:/tmp/.ICE-unix/2796
SHELL is /bin/bash
SSH_AGENT_PID is 2866
SSH_AUTH_SOCK is /tmp/keyring-IFwe6P/ssh
UBUNTU_MENUPROXY is libappmenu.so
USER is oliver
USERNAME is oliver
XAUTHORITY is /home/oliver/.Xauthority
XDG_CONFIG_DIRS is /etc/xdg/xdg-gnome-shell:/etc/xdg
XDG_CURRENT_DESKTOP is GNOME
XDG_DATA_DIRS is /usr/share/gnome-shell:/usr/share/gnome:/usr/local/share/:/usr/share/
XDG_SEAT_PATH is /org/freedesktop/DisplayManager/Seat0
XDG_SESSION_COOKIE is d96aad65fd743b76159d1e0900000007-1324698243.576851-1280198017
XDG_SESSION_PATH is /org/freedesktop/DisplayManager/Session1
XMODIFIERS is @im=ibus

 

可以看到由于while是将hash的key和value分别放到数组里面,并没有对于key的数值进行排序, 所以得到的结果和排序后的结果差异很大。

 

7. undef

undef就是一个标量未初始化;我们可以看下面的例子

#!/usr/bin/perl
# conditionals.pl by Bill Weinman <http://bw.org/contact/>
# Copyright (c) 2010 The BearHeart Group, LLC
#

use strict;
use warnings;

main(@ARGV);

sub main
{
my $x= undef;
message("x is $x");
$x= '';
message("x is $x");
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

得到的结果为:

Use of uninitialized value $x in concatenation (.) or string at /home/oliver/script/perl/Exercise Files/05 Conditionals/undef.pl line 13.
x is
x is
此时显示第十三行报错;提示我们尝试输出了一个没有被初始化的标量, 第二次输出的时候, 此时x的赋值为空,输出也为空。

 

我们下面初始化一个isnum的子函数, 来看undef 和define的差别:

#!/usr/bin/perl
#

use strict;
use warnings;

main(@ARGV);

sub main
{
my $x= 'value';
if(defined isnum($x)){
message("x is a number ($x)");
}else{
message("x is not a number");
}
}

sub isnum
{
my $n = shift;
return $n unless defined $n;
if ($n =~/[^0-9]/){
return undef;
}else{
return $n;
}
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

此时我们得到的输出为:

x is not a number

如果我们将value的数值改为42,得到的输出为:

x is a number (42)

如果我们将value的数值改为0, 得到的输出为:

x is a number (0)

此时我们如果再运行下面的代码,即删除defined

#!/usr/bin/perl

use strict;
use warnings;

main(@ARGV);

sub main
{
my $x= '0';
if(isnum($x)){
message("x is a number ($x)");
}else{
message("x is not a number");
}
}

sub isnum
{
my $n = shift;
return $n unless defined $n;
if ($n =~/[^0-9]/){
return undef;
}else{
return $n;
}
}

sub message
{
my $m = shift or return;
print("$m\n");
}

sub error
{
my $e = shift || 'unkown error';
print("$0: $e\n");
exit 0;
}

我们得到的输出为:

x is not a number

但是,如果我们加上defined,得到的输出为

x is a number (0)

 

这个就是说明了undef和defined的差别,也就能让我们对于一个数值没有被初始化的标量报错信息有了直观的认识。





 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
















 

 

 

 

 

 



 

posted on 2011-12-25 17:45  韩英武  阅读(344)  评论(0编辑  收藏  举报