#!/usr/bin/perl -w

#################################################################
# List 究竟是什麼東西?
@data = ((("Slow"), "and", ("sure")), "wins", ("the", "race"));
# 這樣寫效果一樣:
# @data = ("Slow" => "and", "sure" => "wins", "the" => "race");
for ($i=0; $i<=$#data; ++$i) {
    print " $i:$data[$i]";
}
print "\n";

%dt = @data;
foreach $key (keys %dt) {
    print " $key:$dt{$key}";
}
print "\n\n";

printf "%d + %d = %d\n", (3, 5, 3+5);
printf ("%d + %d = %d\n", 3, 5, 3+5);

@data = (@data, 97, 59, (reverse @data));
for ($i=0; $i<=$#data; ++$i) {
    print " $data[$i]";
}
print "\n\n";

#################################################################
# range operator
foreach (5..8, 1..4) { # 效果和這個一樣: foreach (5,6,7,8,1,2,3,4) {
    print " $_";
}
print "\n";

#################################################################
# Array slice

@months = qw(xxx Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
foreach (@months[7,5..7,2]) {
    print " $_";
}
print "\n";

%days = ("Jan"=>31, "Feb"=>28, "Mar"=>31, "Apr"=>30, "May"=>31, "Jun"=>30,
       "Jul"=>31, "Aug"=>31, "Sep"=>30, "Oct"=>31, "Nov"=>30, "Dec"=>31);
foreach (@days{"Jul", "May", "Jun", "Jul", "Feb"}) {
    print " $_";
}
print "\n";

#################################################################
# Reference

# reference to scalar
$treasure = "gold";
$hint = \$treasure;
print "$hint: $$hint\n";

# reference to array
@treasure = ("gold", "silver", "diamond", "crystal");
$a_hint = \@treasure;
print "$a_hint: (", $#$a_hint+1, " elements)";
for ($i=0; $i<= $#$a_hint; ++$i) {
    print " $$a_hint[$i]";
}
print "\n";

# reference to hash
%treasure = ("gold"=>2, "silver"=>3, "diamond"=>18, "crystal"=>5);
$h_hint = \%treasure;
print "$h_hint:";
foreach (keys %$h_hint) {
    print " $_:$$h_hint{$_}";
}
print "\n\n";

# 參考到參考到參考的參考 ...
$hearsay = \$hint;
$legand = \$hearsay;
print $legand, " ", \$hearsay, "\n";
print $$legand, " ", $hearsay, " ", \$hint, "\n";
print $$$legand, " ", $$hearsay, " ", $hint, " ", \$treasure, "\n";

# 用大括號 { ... } 分析/表達複雜的 reference:
print "$$$$legand ${${${$legand}}}\n\n";

# "箭頭表示法"
print "$a_hint: (", $#$a_hint+1, " elements)";
for ($i=0; $i <= $#$a_hint; ++$i) {
    print " $a_hint->[$i]";
}
print "\n";

print "$h_hint:";
foreach (keys %$h_hint) {
    print " $_:$h_hint->{$_}";
}
print "\n\n";

# anonymous array: 以下兩片段效果相同, 只不過上半段的陣列有名字;
# 下半段的陣列沒有名字; 
@language = ("perl", "c", "java", "python", "basic");
$rl = \@language;
for ($i=0; $i <= $#$rl; ++$i) {
    print " $rl->[$i]";
}
print "\n";

$rl = ["perl", "c", "java", "python", "basic"];
for ($i=0; $i <= $#$rl; ++$i) {
    print " $rl->[$i]";
}
print "\n";

# anonymous hash: 以下兩片段效果相同, 只不過上半段的 hash 有名字;
# 下半段的 hash 沒有名字; 
%language = ("perl"=>"flexible", "c"=>"efficient", "java"=>"hot",
    "python"=>"structured", "basic"=>"classical");
$rl = \%language;
foreach (keys %$rl) {
    print " $_:$rl->{$_}";
}
print "\n";

$rl = {"perl"=>"flexible", "c"=>"efficient", "java"=>"hot",
    "python"=>"structured", "basic"=>"classical"};
foreach (keys %$rl) {
    print " $_:$rl->{$_}";
}
print "\n\n";

# nested anonymous hash/array
$x = { "Mon"=>[1,2,3,4], "Tue"=>[5,6], "Wed"=>[7,8,9] };
# 如何把 "9" 這個元素改成 0?
# 請先看執行結果, 並試著自己寫程式...
$x->{"Wed"}->[2] = 0;
${${$x}{"Wed"}}[2] = 0; # 這樣寫也可以
${$x}{"Wed"}->[2] = 0; # 這樣寫也可以
${$x->{"Wed"}}[2] = 0; # 這樣寫也可以
# 如何把每個 key, 每個陣列的元素個數, 及每個陣列的內容, 全部都印出來?
foreach $k (keys %$x) {
    print "$k (", $#{$x->{$k}}+1, "): ";
    foreach $v (@{$x->{$k}}) {
	print " ", $v;
    }
    print "\n";
}
print "\n";

# shallow copy vs. deep copy

# 下面這三句, 那一句才是正確的 deep copy? 請畫圖表示各句效果.
$y = $x;
# %$y = %$x;
# foreach $k (keys %$x) { @{$y->{$k}} = @{$x->{$k}}; }

$y->{"Wed"}->[2] = -1;
print '原來的變數 $x 是否也變了? ', $x->{"Wed"}->[2], "\n";

