前言
我的学习过程中有一个很明显的特点,先知道是什么,最后才知道为什么,不知道这样好不好?
学习perl的网站
http://faq.perl.org/
books
Programming Perl(Camel book)
Perl 5 Pocket Reference
Offical Perl newsgroups is comp.lang.perl
其实,perl语言是这么一个流程:在内存中保存他的输出;更新内存;并且打印它
基本语法day01
1.scalar : a number,a string,You can act on a scalar value with operators(like additioon or concatenation),You can read scalars from file and devices and write to them as well.
2.在整数常量中,如果数字特别巨大,可以使用 21_323_123_987_365表示
3.Others Nondecimal 0377 #377 octal 0xff #FF hex, 0b11111111 #also 255 decimal
4.如果在程序中使用utf-8,这样 use utf8;
5.在字符串的使用中,需要注意’ ‘的内容,里面除了“‘”和“",其余的都代表 他们自己本身,如果想得到一个“\”,那么就使用“\”,为了表示”’“,同样使用“\“转义; 与此对应的是,双引号的使用,你可以想象成c语言中的双引号
6.使用 “.”符号进行链接剪切等操作 For example:
"hello" . "world" #same as "helloworld"
"hello" ' ' . "world" # same as 'hello world'
'hello world' . "\n" #same as "hello world\n"
7.重复字符串”x”,对,你没看错,就是小写字母x,
"yubo" x 3
"yubo" x (3+1)
5 x 4.8 #same as “5555” 最后一个需要说明一下,在操作符 “x”的左边,我们称之为左值,你可以看成源操作数 ,符号右边是右值,你可以看成是目的操作数,4.8被自动转换为4.
8.在数字和字符串之间自由转换,这只是取决于你自己用在标量的的操作符, 比如,“+”系统默认为左值和右值为数字,“.”左右值默认为字符串 , 比如,”12” * “3”就是36,即便在“12yubo34” * 3的结果依旧是36
day02
1.变量
用$表示,$name,…还可以用于数组
2.变量赋值
$bin = 12;
$asd = $bin *2;
另外需要注意的是在perl变量中,“ ”与shell中的“ ”一样, 在比较多的变量中,使用${varible}调用其值
3.打印特殊符号,先找到ascii码,然后使用 chr()函数,$alef = chr(0x05D0); 即可。
4.有关perl的运算符的优先级和结合性(结合性依次降低)
结合性 运算符
left ->
++ --
right **
right \ ! ~ + -(unary operators)
left =~ !~(?)
left */%x
left =-.(binary operations)
left <<>>
< <= > >=
== != <=>
left &
left | ^
left &&
.. ...(?)
right ?:(conditional operator)
right = += -= .=(and similar assignment operators )
left , =>
right not
left and
left or xor
没有必要记住上面的这些东西,如果你找不到你想要的运算顺序,尽管加上括 号即可(parenthses),the same time:
Numeric String
== eq
!= ne
< lt
> gt
<= le
>= ge
##perl中的bool类型 1.如果返回的值是0为false,其他为true;
2.如果返回的是一个字符串,‘ ’意味着false;其他意味着成功
3.如果还有其他情况,请转化为这两种情况。
1.1,Getting User Input
For example:
$line = <STDIN>;
if ($line eq "\n")
{ print "That was just a blank line!\n";}
else { print "The line of input was: $line";}
这样就是用户从屏幕标准输入了。
1.2
The chomp Operator
它的作用简单说就是作用于一个变量(输入的值),把结束符(newline)去掉,
这一步在以后的编程中很有用的,上面的例子,我们一般情况下这样做:
chomp($text =
如果你以这样的方式写出这样的程序,那么就没有换行输出了,因为它自动将换行符去掉了。
1.3 in short,chomp也是一个简单的函数,也有返回值,他的返回值就是清除字符的个数,但是这种用法和我们上面不太一样,是这样
$yubo = <STDIN>;
$NAME = chomp $yubo;
输出的结果是1.
1.4 The while control construction 同c语言的一样,很简单的。
1.5使用defined function
$yubo = <STDIN>;
if ( defined($yubo) ) {
print "The input was $yubo\n";}
else { print "No input available\n";}
lists and array
1.
$fred[0] = "yubo"; print $fred[0]; #perl的数组没有限制,随便用
2.列表
(1,2,3) ("yubo",4.5) (1..100)
2.2 The qw Shortcut
qw( fred yubo hechun wilma dino )# 等同于有双引号的列表
qw! yahoo\! google ask msn ! #include yahho! as an element
2.3 List Assignment
- ($fred, $yubo, $hechun) = (“yubo”, “hechun”, undef)
- ($rocks[0], $rocks[1], $rocks[2], $rocks[3]) = qw/yubo hechun mica yubo/;
3.在给数组赋值的时候,可以在数组前面加上@,这样就全部赋值了。例如,
@rocks = qw/ bedrock slate lava /;
@tiny = ();# the empty list
@giant = 1..1e5; # a list with 100000 elements
- pop and push
The pop operator takes the last element off of an array and returns it @array = 5..9;
$yubo = pop(@array); #$yubo gets 9,@array now has (5,6,7,8)
$barney = pop @array;#barney gets 8,@array now has (5, 6, 7)
push operator
push(@array,0) # @array now has (5,6,0)
push @array,8 # @array now has (5,6,0,8)
push @array,1..10; # @array now has those 10 new elements
- The shift and unshift operators
这shift运算符就是将数组内的元素按从左到右的位置依次取出,
剩下的数组去掉这个元素,取没时用0填充。
@yubo = qw# hechun wuhan wangyang #; $m = shift (@yubo); $n = shift @yubo; unshift play an oppose play vs shift,and it used to be filled with elements. unshift(@yubo, 5); unshift @yubo, 5;
6.分离数组
1.splice就是分离数组的符号,有4个参数,其中
@yubo = qw(apple, dino, hechun, love);
@removed = splice @yubo, 2; #remove everything after hechun
#@removed is qw(hechun,love)
#@yubo is qw(apple, dino)
2.第三个参数就是要删除元素的个数
@removed = splice @yubo, 1, 2; #@removed is qw(dino, hechun)
#@yubo is qw(apple, love)
3.这第四个参数就是你放置要取代的元素,这个数不必和你取出去的相同。
@removed = splice @yubo, 1, 2, qw(wilma);
当然,你可以不用去掉任何元素,只要使第三个参数变0即可。
7.@和$ 当变量中含有@(list-var)时要注意使用”"转义,还有注意数组的使用。
8.foreach 一个loop的控制变量,一个普遍的用法是用$var读取list的内容,如下:
@yubo = qw(yu hechun hehe); foreach $num (@yubo){ print "$num\m"; }
注意这时的$num不是简单的@yubo的元素的复制,而是实实在在的东西, 你只要改变$num的内容,也能影响@yubo的内容。我们可以使用$_作为foreach的 默认控制变量,打印语句可以直接使用print;
- reverse
以反序输出内容,如果是单词,按首字母排序。
- sort
如果是单词,按首字母排序;如果是数字,也是按照首位的大小排序。
以上几个内建函数的对象是list(我觉得),使用的时候注意, scalar和list的混用的情况,注意内容与类型的对应要正确。 作者说了,这部分的理解决定了你这一辈子是否使用perl的关键因素, 没有之一。
define
sub subroutine-name{ }
perl automatically
stores the parameter list in the special array named @_, you can access it to get number of argument and the value of those arguments. For example,$_[0],$_[1]…
check number of paraments
在函数内部使用 @_
就是参数个数
sub max{ if (@_ != 2){ print "wrong\n"; } else { print "yes\n"; } } $n = &max(19,23);
下面的例子,把函数的规则总结的不错
$maxinum = &max(3, 5, 10, 4, 6); sub max { my($max_so_far) = shift @_; # private variable foreach (@_){ #look at the remaining arguments if ($_ > $max_so_far){ $max_so_far = $_; } } $max_so_far; } print "The maxinum is $maxinum\n";
my(var)也叫Lexical(my) Variables,这个变量位于最小的块中,可以是代码块 或者文件。利用关键词my去声明局部变量。
foreach (1..10){
my($square) = $_ * $_;
print "$_ square is $square\n";
}
use strict;
在代码中你只要使用了这条语句,在使用变量的时候就必须先声明后使用, 不然编译器就报告失败.当然对于内建变量是不会报错的, please use it possiblely. 此时感觉perl真是非同一般,你只要使用了strict,那么程序中的变量就要使用 my去声明。
return value
use strict;
my @name = qw(yubo hechun xixi qianqian);
my $result = &which_element_is("xixi",@name);
sub which_element_is {
my($what, @array) = @_;
foreach (0..$#array){
if ($what eq $array[$_]){
return $_;
}
}
-1;
}
use state
What is state?Please see example follwing:
#!/use/bin/perl
use strict;
sub marine {
my $n += 1;
print "$n\n";
}
foreach (1..5) {
&marine;
}
output:五个1。原因在这里很简单,就是my把变量局限于子函数内, 请不疑惑,尽管我们的$n 在sub marine内,但是,在foreach的调用中, 整体已经过去了,所以只会输出五个1(??)
Stardard Input And Output
典型例子
while (defined($line = <STDIN>)){
print "I saw $line";
}
同样的表达可以是
while (<STDIN>){
print "I saw $_";
}
foreach (<STDIN>){
print "I saw $_";
}
# Ctrl + D
<>
Reading variables from input,
while (<>) {
chmop;
print "It was $_ that i saw";
}
Filehandle
名字最好使用大写字母,这样有好几个优势。
open CONFIG, 'dino'; # dino is filename
open config, '<dino';
open BEDROCK,'>fred'
you can use a “three-argument” open:
open CONFIG, '<', 'dino';
open BEDROCK, '>', '$file_name';
open CONFIG,'<:encoding(UTF-8)', 'dino';
open LOG, '>>:encoding(UTF-8)', &logfile_name();
die statement
if (! open LOG, '>>', 'logfile') {
die "Cannot create logfile: $!"
}
这个判断语句就是判断是否能创建logfile文件,不能的话返回一个数值, 这个值就是不能的含义,在这里,可以把die和pirnt联系起来,共同报错。
filehandle 补充
Recently i thought sth deeply,English is my shortcut to learn linux kernel and others, and lack of indpendent of thinking.
use strict;
use warnings;
open (my $yubo, '>', 'log');
print $yubo "My first report generated by perl\n";
close $yubo;
print "done\n";
这就是一个典型的文件句柄。open函数可以传入3个参数。
第一个, $yubo,是在 open()调用中定义的标量,第二个参数是读写文件的方式,第三个是文件路径。
文件的内容仍在磁盘上,并不在$yubo变量中,可能你往句柄中写入内容, 东西就会在文件中保存。
这个$yubo就可以类推c语言中的文件描述符(fd),有意思吧!
open or die
open(my $yubo, ‘>’, ‘no_exist/file’) or die;
下面这种用法结合前面几种的方法
my $filename = 'No_exist_file';
open(my $yubo, '>', $filename) or die "could not open $filename $!";
# return error information
@ARGV
当时偷懒了,只是简单的记录下来,并不知道什么意思。现在再重新整理整理。 顾名思义,@ARGV就是一个参数,这个参数接受外部变量,这里,这个变量就是某个路径上的文件,将该文件上的内容输出。
@ARGV = ("file1","file2");
while ($line = <>) {
print "$line\n";
}
上面的东西,一看就是菜鸟写的,应该简单一点是这样
@ARGV = ("file1");
while (<>) {
print "$_";
}
hash
For example:
$family_name{'yubo'} = 'flintstone';
$family_name{'hechun'} = 'love';
foreach my $person (qw <yubo hechun>) {
print "I've heard of $person $family_name{$person}.\n";
}
Hash Assignment
my %new_hash = %old_hash;
my %last_name = (
'Yu' => 'bo',
'He' => 'chun',
);
foreach my $first (qw <Yu He>) {
print "$first in @last_name{$first}.\n";
}
上面的hash赋值完后还可以使用 $hash{“d”} = 1; 的方式解决。 还有一种方式可以赋值:
my %last_name;
$last_name{"fred"} = "hehe";
$last_name{"yubo"} = "bo";
$last_name{"he"} = "chun";
注意,赋值的时候使用%,使用的时候却是$
下面这句话改变了 key 和 value 的位置。
my %inverse_hash = reverse %any_hash;
Hash functions: keys and values
my %hash = ('a' => 1, 'b' => 2, 'c' => 3);
my @k = keys %hash;
my @v = values %hash;
foreach (@k) {
print "$_\n";
}
这样就会打印hash的key,但是有一点请注意,perl不保证输出的顺序, 也就是你最好不要期望得到你想要的顺序。又但是,keys 和 values函数 可以保证此时的值相对应,例如,上面的例子@k会打印出c b a,那么打印 的@v一定是3 1 2
There is another function:
my $count = keys %hash;
$count的值就是hash函数中的对数。
Hash function: each
while ( ($key, $value) = each %hash) {
print "$key => $value\n";
}
After sorted hash
foreach $key (sort keys %hash) {
$value = $hash{$key};
print "$key => $value\n";
}
The exists Function,to see whether a key exists in the hash, use the exists function,if true
以上面的代码为例:
if (exists $hash{"a"}) {
print "Hey, there exist\n";
}
if (!exists $hash{"d"}) {
print "NO exist!\n";
}
不知道我的思路是否有问题,$hash,@hash,%hash三者之间有着某种联系, 虽说hash是用来定义的,但它仅仅是定义吗?在其他的外部调用中,我们 反而使用的是$hash{“”},在当时学习@hash和$hash也有同样的问题。
The %ENV hash
print "PATH is $ENV{path}\n";
Exercises
write a perl file, output the times of that have read from terminal. For example, input “yubo,hechun,yubo,hechun” output the numbers”yubo 2…hechun 2”
my(@words, %count, $word); # declare
chomp(@words = <STDIN>); # input
foreach $word (@words) {
$count{$word} += 1;
}
foreach $word (keys %count) {
print "$word was seen $count{$word} time . \n";
}
自己从这个程序中稍微理解了hash的原理,其中最后一个比较有意思, 在count hash中$word作为keys,so the value is $count{$word}.
下面的例子与上面的很类似
$longest = 0;
foreach my $key (keys %ENV) {
my $key_long = length($key);
$longest = $key_long if $key_long > $longest;
}
foreach my $key (sort keys %ENV) {
printf "%-s{longest} %s \n.$key, $ENV{$key}";
}