• Perl 学习手札之四:variables and value


    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的差别,也就能让我们对于一个数值没有被初始化的标量报错信息有了直观的认识。






















  • 相关阅读:
    this指向
    作用域链
    入门
    一、servlet之初见
    jdbc之mysql
    第六章、树和二叉树
    第七章、暴力求解法
    机试
    第十三章、字符串
    栈和队列
  • 原文地址:https://www.cnblogs.com/hanleilei/p/2287108.html
Copyright © 2020-2023  润新知