Perl 学习手札之四:variables and value
Perl 学习手札之四:variables and value
2011年12月25日
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");
exit0;
}
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");
exit0;
}
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");
exit0;
}
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");
exit0;
}
注意转义字符: \
有时候我们可以用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");
exit0;
}
此时的输出为:
1:two:3:4
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");
exit0;
}
注意此时此时用到 $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");
exit0;
}
此时的输出为: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");
exit0;
}
此时相应的输出为:
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");
exit0;
}
此时的输出为:
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");
exit0;
}
运行一次的输出为:
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");
foreachmy$k (sortkeys%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");
exit0;
}
输出为:
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("===================");
foreachmy$k (sortkeys%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");
exit0;
}
得到的结果如下所示:
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("===================");
foreachmy$k (sortkeys%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");
exit0;
}
得到的输出如下所示:
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/loca l/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=5f69a46a6a 5ae16b8faa144400000416
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:/u sr/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/ol iver-Computer:/tmp/.ICE-unix/2796
===================
DBUS_SESSION_BUS_ADDRESS is unix:abstract=/tmp/dbus-EICx1DlHFb,guid=5f69a46a6a 5ae16b8faa144400000416
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:/u sr/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/loca l/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/ol iver-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就是一个标量未初始化;我们可以看下面的例子 得到的结果为:
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$nunlessdefined$n;
if ($n =~/[^0-9]/){
returnundef;
}else{
return$n;
}
}
sub message
{
my$m = shift or return;
print("$m\n");
}
sub error
{
my$e = shift || 'unkown error';
print("$0: $e\n");
exit0;
}
#!/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$nunlessdefined$n;
if ($n =~/[^0-9]/){
returnundef;
}else{
return$n;
}
}
sub message
{
my$m = shift or return;
print("$m\n");
}
sub error
{
my$e = shift || 'unkown error';
print("$0: $e\n");
exit0;
}