『初めてのPerl第5版』はじめに〜第8章
初めてのPerl第3版は消滅しろ!
ということで「やっぱ第5版」ってことでやり直してましたw
目次と正誤表は以下のサイトで!
サンプルダウンロード
wget http://examples.oreilly.com/9780596520113/llamasamp.zip unzip llamasamp.zip tree sample_files sample_files/ ├── README ├── fake_date ├── lnr_example ├── numbers ├── pattern_test ├── sortable_hash ├── text_files │ ├── bamm-bamm │ ├── barney │ ├── betty │ ├── dino │ ├── fred │ ├── pebbles │ ├── sample_text │ └── wilma └── which_dbm
以下先日の投稿を編集&追記しつつ第1章〜第8章まで!
はじめに
以下適当なつぶやき。
「もしあなたがPerlプログラミン言語を学ぶために最初の30〜40時間を費す最良の方策を探しているなら〜」
お、つまりこの連休中に終わるってことですね!←
(この時はまだ、第3版がだめなんてことには気づいていないのであった…)
本を書くとムショに行かなくても良いことになるらしい。
脚注の内容がマニアック過ぎる!
しかも「脚注の多くは、単なるコンピュータージョークに過ぎません」
自覚してやってるwww
「Perlはラクダにちょっと似ています。」
確かに。
明らかに本を片手にブログを読まないとわからないつぶやきを残して次へ。
1章 Perl入門
いつの間にか読み終わってた。
練習問題に行く前に練習問題も解き終わってた←
<追記>
第5版ではsayの話が追加されてました。
use 5.010; use strict; use warnings; say "Hello World!"; #sayは自動で改行が入る print "Hello World!"; #printはそのまま表示するだけなので改行が入らない
ただuse 5.010を追加しないと最新のPerlでも怒られるので、
使わね〜って思いました。
2章 スカラーデータ
ここからコードを書いて来ますが、そのほとんどが本に載っているコードとは違うと思います。
本と照らしあわせながらこんな書き方もするんだぁ、とかmyをつける場合はこうやるんだぁとか思いながら、実行できる環境で確認しながらやると勉強になるかもしれないしならないかもしれないし…。
2.2 文字列
- 2.2.3 文字列演算子
↓なにこれ知らなかったw
print 5 x 4 #5555と出力
文字列 * 数字
で出来る言語もあるけどあえてxなんですね。
- 2.2.4 数値と文字列の自動変換
↓ぎゃぁー!
print "5fred23425" * " 3" #色々無視して15と出力
(Perlつえーって思った瞬間でした…)
2.8 chomp演算子
chompとか出会わない。。。
2.9 while制御構造
(なんかwhile分の扱いがひどかったなぁ、まあその程度のものなんだろうけど)
2.9 未定義値
2.10 defined関数
未定義の変数は素通りできても警告は履くよね。
2.11 練習問題
↓とりあえず練習問題の一部。
use strict; use warnings; chomp(my $moji = <STDIN>); chomp(my $cnt = <STDIN>); print "$moji\n" x $cnt;
(ちなみにこれより下のソースではuseはめんどくさいので書かれてませんが、ちゃんと使っているので悪しからず。
またmyとかも本には書いてませんがここでは適宜つけていきます。)
ふう、次!
3章 リストと配列
3.1 配列の要素にアクセスする
うっ…
my @fred; $fred [0]=1; print $fred[0.248572309],"\n"; #添字は小数点以下切捨てられて出力は1
3.2 配列の特別なインデクス
$#ってなんかおえ〜
my @fred; $fred [0]='start'; $fred [99]='end'; print $fred[0],"\n"; print $fred[50],"\n"; #fred[1~98]はundefなので怒られる print $fred[99],"\n"; #oeeee $#fred = 0 ; print $fred[0],"\n"; print $fred[99],"\n"; #怒られる print $#fred,"\n";
なるほど-1って使えたんだ。
$#fred = 99 ; $fred[$#fred]='The End'; print $fred[-1],"\n"; #The End が表示される
3.3 リストリテラル
- 3.3.1 qwショートカット
リストの書き方って便利だよね。
(出力結果は随時実行して確かめて見てください。)
my @num = 1..10; my @fred = qw/hoge fuga piyo /; my @mark = qw{/usr/bin/perl /etc/hosts }; print $num[0],"\n"; print $num[9],"\n"; print $fred[0],"\n"; print $fred[1],"\n"; print $fred[2],"\n"; print $mark[0],"\n"; print $mark[1],"\n";
..をたくさん使いたいときは()で囲う必要があるみたい
my @num_ = (0, 2..6, 20..25); my $i=0; while($i <= $#num_){ print $num_[$i],' '; $i+=1; } print "\n";
3.4 リスト代入
リスト代入
(my $hoge, my $fuga, my $piyo) = ("hoge", "fugafuga", "piyopiyopiyo"); print $hoge,"\n"; print $fuga,"\n"; print $piyo,"\n";
こうも書けるよね
my ($hoge, $fuga, $piyo) = ("hoge", "fugafuga", "piyopiyopiyo"); print $hoge,"\n"; print $fuga,"\n"; print $piyo,"\n";
溢れたら無視するんだって
my ($hoge, $fuga, $piyo) = 1..10; #最初の3つだけ代入されてあとは無視される print $hoge,"\n"; print $fuga,"\n"; print $piyo,"\n";
変数の方が多いとundefが入るだけ
my ($hoge, $fuga, $piyo) = qw/hoge fuga/; #最初の3つだけ代入されてあとは無視される print $hoge,"\n"; print $fuga,"\n"; print $piyo,"\n"; #怒られる
こういうのってよく関数作るときに利用されますよね。
ていうかスルーしてたけど値の交換ってこれだけで出来るんだ!
my ($hoge, $fuga) = qw/hoge fuga/; print $hoge,"\n"; print $fuga,"\n"; ($hoge, $fuga) = ($fuga, $hoge); print $hoge,"\n"; print $fuga,"\n";
空のリストは無視されます。
my @array0 = qw/hoge undef fuga/; #この場合はundefはただの文字 print $array0[0], "\n"; print $array0[1], "\n"; print $array0[2], "\n\n"; my @array1 = ("hoge", undef, "fuga"); #この場合はundefはただの文字 print $array1[0], "\n"; print $array1[1], "\n"; #意図的にundefを挿入している→怒られる print $array1[2], "\n\n"; my @tmp = (); my @array2 = ("hoge", @tmp, "fuga"); #この場合はundefはただの文字 print $array2[0], "\n"; print $array2[1], "\n"; #本の通りならundefは入っていないはずだがundefが入ってしまっている print $array2[2], "\n"; print @array2.length, "\n"; #配列の長さも3となる
my @tmp = ();
とすれば空のリストはundefでなく空として処理されるんですね。
3.5 pop演算子とpush演算子
ぽっぷ
後ろから順々に出してく
my @array = (5..9); print @array."\n"; print "\n"; while(@array.length >0){ print pop(@array)."\n"; print @array."\n"; print "\n"; }
ちょっとここでは関係ないけど知らなかったのは以下。
,で区切るとリストで表示はされるのは普通か。
.で区切ると@arrayが配列の大きさを表示する方の変数として解釈されている。
ふーん、ですね。
(これはあとから出てくるスカラーコンテキストとリストコンテキストが関係してます。)
my @array = (5..9); while(@array.length >0){ print pop(@array),"\n"; print "配列の中身を表示:",@array,"\n"; #,で区切る print "配列の長さを表示:".@array."\n"; #.で区切る print "\n"; }
ぷっしゅ
末尾に追加していく
my @array = (5..9); my @pushed = (); while(@array.length >0){ push(@pushed, pop(@array)); print @pushed,"\n"; print @pushed."\n"; print "\n"; }
あとしふととあんしふとは先頭からちょめちょめするらしいよ←適当!(俺が)
my @array = (5..9); my @unshift; while(@array.length >0){ unshift(@unshift, shift(@array)),"\n"; print @unshift,"\n"; print "配列の中身を表示:",@unshift, ,"\n"; #,で区切る print "配列の長さを表示:".@unshift."\n"; #.で区切る print "\n"; }
3.6 配列を文字列の中に展開する
配列の展開のされ方って色々あるんだね〜
my @rock = qw/stone slate rubble/; print @rock,"\n"; print @rock."\n"; print "@rock\n"; print "hoge @rock fuga\n"; print "hoge",@rock,"fuga\n"; print "hoge".@rock."fuga\n";
おっと、ここでも"2*4"は数字の2って解釈されるんだね。
my @rock = qw/stone slate rubble/; my $x = 2; print "hoge $rock[$x-1] fuga\n"; my $y = "2"; print "hoge $rock[$y-1] fuga\n"; my $z = "2*4"; print "hoge $rock[$z-1] fuga\n"; #すべて結果は同じになる
えー!!配列とスカラーで同じ文字でも違うものとして使えたんだ!
知らなかった…。
my @fred = qw{eating rocks is wrong}; my $fred = "right"; print "$fred[0]\n"; print "$fred[1]\n"; print "$fred[2]\n"; print "$fred[3]\n"; print "$fred\n";
なので表示するときんは気をつけて書かないと予期せぬ結果になる。
my @fred = qw{eating rocks is wrong}; my $fred = "right"; print "This is $fred[3]\n"; #wrong print "This is ${fred}[3]\n"; #right print "This is {$fred}[3]\n"; #{right} print "This is $fred"."[3]\n"; #right print "This is $fred\[3]\n"; #right
3.7 foreach制御構造
来ましたよforeach
foreach my $array (qw/hoge fuga piyo/){ print "$array\n"; }
知らなかった!!
単なる@arrayの"値"を$valueに代入しているつもりしかなかったけど、
$value自体が@arrayの値そのものなんだ!
とにかく以下を実行。
my @array = qw/hoge fuga piyo/; print @array, "\n"; #スペース無しでくっついて表示される foreach my $value (@array){ $value = "$value "; } print @array, "\n"; #スペースありで表示される
- 3.7.1 Perlお気に入りのデフォルト:$_
ちなみにこの場合の$value(制御変数と呼ばれる)は以下の用に$_で代用できる。
my @array = qw/hoge fuga piyo/; print @array, "\n"; #スペース無しでくっついて表示される foreach (@array){ $_ = "$_ "; } print @array, "\n"; #スペースありで表示される
ちなみにprintって基本的に指定がない場合は$_を表示するだとか。
my @array = qw/hoge fuga piyo/; print @array, "\n"; #スペース無しでくっついて表示される foreach (@array){ $_ = "$_ "; print; print "\n"; } print @array, "\n"; #スペースありで表示される
($_ってこのあとたくさん出てくるけど便利ですねぇ)
- 3.7.2 reverse演算子
あと反転の使い方
print 1..10, "\n"; print reverse(1..10)."\n"; print reverse 1..10 ,"\n"; #ちなみにこれだと変な結果になりますね。まあそうですね? print "\n\n"; #あと変数を使った時 my @hoge = 3..9; my @fuga = reverse @hoge; print @hoge,"\n"; # 元のまま print @fuga,"\n"; # もちろん反転している
- 3.7.3 sort演算子
そーと
print 1..9, "\n"; #123456789 print reverse(1..9), "\n"; #987654321 print sort(reverse(1..9)), "\n"; #12345689
3.8 スカラーコンテキストとリストコンテキスト
スカラーコンテキスト、リストコンテキストの話になりました。
この話はさっきしたprintで,と.で表示される内容が違う、っていうことには関係してそうです。
my @list = 1..10; my $n = @list; print @list,"\n"; #12345678910 print @list."\n"; #10 print $n."\n"; #10
- 3.8.1 リストを生成する式をスカラーコンテキストで使う
reverseの場合
my @moji = qw/hoge fuga piyo/; my @moji_ = reverse @moji; #リストとして代入される my $moji = reverse @moji; # print @moji,"\n"; #元の配列 print @moji_,"\n"; #要素の順番が反転 print $moji,"\n"; #すべての要素をくっつけて一文字にしてそれを反転
print @list,"\n"; #12345678910 print scalar @list,"\n"; #10 print @list."\n"; #10
3.9 リストコンテキストでを使う
上の方でやった練習問題に対して適用。
print "最初に文字を入力してEnter、次に回数を入力してEnter、ちなみにそれ以降の何を入力しても無視され>ます。\n"; print "あとCtrl+Dで入力終了\n"; chomp(my @moji = <STDIN>); print "$moji[0]\n" x $moji[1];
3.10 練習問題
はい!っていうことで練習問題3つくらいあったけど全部含ませてみた。
(↓超適当だけど気にしない)
print "基本的に入力終了は自分で決めて。入力終了はCtrl+Dだよ\n"; print "人の名前を適当に何人か入力してちょ\n"; chomp(my @hito = <STDIN>); print "あんたが入力したのはこの人達だね\n"; foreach (@hito){ print $_,"\n"; } print "逆順に出力しても全然面白くないよね。。。\n"; foreach (reverse @hito){ print $_,"\n"; } print "ソートしてみたけどおもしろい、これ?\n"; foreach (sort @hito){ print $_,"\n"; } print "やめたくなったらCtrl+Cで強制終了してくれ\n"; while (1){ print "0~".(scalar @hito -1)."までの数字を入力してみて!\n"; chomp(my $num = <STDIN>); print "その番号に対応する人は、".$hito[$num]."だよ!\n"; }
ということで次行くぜ!!
4章 サブルーチン
サブ!マリン!バカ!
4.1 サブルーチンを定義する
4.2 サブルーチンを起動する
4.3 戻り値
Perlのサブルーチンも最後に計算・評価した結果を戻り値に出来るんだね。
sub marine { $_[0] + $_[1]; } print &marine(1,2),"\n"; #3を出力
間違って最後にprintにするとprintが成功したという意味で1を返しちゃう。
sub marine { $_[0] + $_[1]; print "hoge"; } print &marine(1,2),"\n"; #hoge1と表示されてしまう
4.4 引数
↓は動作するけどかっこが悪いらしい。
sub max { if ($_[0] > $_[1]){ $_[0]; }else{ $_[1]; } } print &max(4,2),"\n";
4.5 サブルーチンの中でプライベートな変数
以下みたいにサブルーチン内だけで使用できるレキシカル変数を定義できるよ。
sub max { my($a, $b) = @_; if ($a > $b){ $a; }else{ $b; } } print &max(4,2),"\n";
(好みじゃない?)
4.7 レキシカル変数(my変数)についての注意事項
localとmyの違いがやっとわかったぜ!
(だがしかし!第5版にlocalは出てこない!)
4.8 use strictプラグマ
4.9 return演算子
my @names = qw/take yuji keiko soya kota akira taro/; chomp(my $name = <STDIN>); if(&iru($name,@names)){ print "iruyo\n"; }else{ print "inaiyo\n"; } sub iru{ my($name, @list) = @_; foreach(@list){ if($name eq $_){ return 1; } } undef; }
4.10 スカラー以外の戻り値
4.11 永続的なプライベート変数
4.12 練習問題
つまらないのでやらなかった。
ふぅ、次!
5章 入出力
5.1 標準入力からの入力
あくまでショートカットとのこと
#入力するごとに実行を行う while (<STDIN>) { print "You saw $_\n"; } #一度入力し終わるのを待ってから実行を行う foreach(<STDIN>){ print "You saw $_\n"; }
5.2 ダイヤモンド演算子からの入力
娘の一言で演算子の命名をするなんていいはなしだなぁ
とりあえず以下のようなファイルhogeを用意。
hoge0 hoge1 hoge2
でもって、以下のPerlコードを適当な名前で保存
# ダイアモンド演算子<>はあくまでファイル名を読み込んで来て、そのファイルの中身を読み込んで行く while (<>) { chomp; print "You saw $_\n"; } # コマンドラインにて以下のようにして実行 $ chmod a+x daia $ ./daia hoge
5.3 起動引数
あと@ARGV変数が出てきたので以下も実行してみた。
print @ARGV,"\n"; foreach (@ARGV) { chomp; print "You saw $_\n"; } # コマンドラインにて以下のようにして実行 $ ./daia hoge
<>は起動引数にセットされている文字をファイル名と認識してそのファイルを順次読み込む。
@ARGVは単純に起動引数のリストが入っているだけ。
つまり@ARGV→<>って流れになっている。
なので<>が実行される前に@ARGVの中身を変えれば起動引数で指定していされたファイルでなく
プログラムで指定したファイルを<>が読み込むことになる。
ふむふむ
5.4 標準出力への出力
以下のコードはprintのあれこれ
my @list =qw/hoge fuga piyo/; print @list,"\n"; #hogefugapiyoと出力される print "@list","\n"; #hoge fuga piyo と出力される @ARGV = qw/hoge/;; my @hoge_list = <>; #ファイルの中身を配列へ print @hoge_list; #改行付きでそのまま展開される print "@hoge_list"; #改行付き&スペースつきで表示されるためくずれる #chompしようよ chomp(@hoge_list); print "@hoge_list"; #改行なし&スペースつきで表示される
あと、<>のリストコンテキスト
@ARGV = qw/hoge/;; print <>; #ダイアモンド演算子がリストコンテキストで解釈される #print sort <>; こんな風に書くとソートされてから出力される||< *** 5.5 printfによるフォーマット付き出力 - 5.5.1 配列とprintf 使わないなぁ、と思ったら以外にもこのあとの練習問題で標準出力を凝りたい問題があって使った。 *** 5.6 ファイルハンドル これ第3版だと11章だったなぁ。 以降は読んだだけ。練習問題へ。 *** 5.7 ファイルハンドルをオープンする *** 5.8 dieによって致命的エラーを発生させる *** 5.9 ファイルハンドルを使う *** 5.10 標準ファイルハンドルを再オープンする *** 5.11 sayを使って出力する *** 5.12 練習問題 #tacっていうすべてを逆順に読み込むプログラムを作成する if(@ARGV < 1){ die "ファイル名を指定して下さい。"; } foreach(my @list=reverse <>){ chomp; print $_,"\n"; } ** 6章 ハッシュ *** 6.1 ハッシュとは? []をブラケット、{}をブレースと呼ぶ。 テストにはでない。 - 6.1.1 なぜハッシュを使うのか? *** 6.2 ハッシュの要素にアクセスする - 6.2.1 ハッシュ全体を扱う ここまで読んでみて、すぐ3.10の練習問題をハッシュを使えば短く出来るんじゃないかって思ってやってみる。 本はちゃんと読んでないけど。 >|perl| my %names = ( "take" => 1, "yuji" => 1, "keiko" => 1, "soya" => 1, "kota" => 1, "akira" => 1, "taro" => 1); #このハッシュいるの?wっていう冷徹なツッコミは断固として拒否する! #いいじゃない、短くなったんだから。 chomp(my $name = <STDIN>); if($names{$name}){ print "iruyo\n"; }else{ print "inaiyo\n"; }
それにしてもPerlってすごいよねー、
これだけやっても下の変数名が”重複してない”ことになるんだから。
#全部aでも別物として認識する my $a = 1; my @a = 1..5; my %a=( "hoge" => "hogeko", "fuga" => "fugao", ); sub a{ 1234; } print $a,"\n"; print $a[0],"\n"; print $a[3],"\n"; print $a{hoge},"\n"; print $a{fuga},"\n"; print &a,"\n";
ハッシュってコンテキストによってどうなるのかを調べてみる。
# なんだこんな定義でも勝手にペアにしてくれるのか… my %hash_list=( "hoge", "hogeko", "fuga", "fugao", ); print $hash_list{hoge},"\n"; my $n = %hash_list; # わからんw 読み進めたら「Perlをメンテナンスする人の内部デバッグ情報を表す文字列」を返すらしい my @list = %hash_list; # 単純に上で定義してるようなリストになる print $n,"\n"; print @list,"\n";
- 6.2.2 ハッシュの代入
- 6.2.3 太い矢印
6.3 ハッシュ関数
- 6.3.1 keys関数とvalues関数
- 6.3.2 each関数
# 可読性を考慮して太矢印で書きましょう my %hash_list=( "hoge" => "hogeko", "fuga" => "fugao", "yamada" => "taro", "satou" => "keiko", ); #keysとvaluesの使い方 #リストコンテキスト my @keys = keys %hash_list; my @values = values %hash_list; print @keys, "\n"; print @values, "\n"; #keysとvaluesの使い方 #スカラーコンテキスト my $keys_num = keys %hash_list; my $values_num = values %hash_list; print $keys_num, "\n"; print $values_num, "\n"; #eachを使ったループ文 while(my($key, $value) = each %hash_list){ print "$key => $value\n"; }
あくまでeachは%hashのkey/valueを順番に出して行っているだけ。
そしてwhile文も出されたリストのをスカラーコンテキストとして読み取ってリストの個数が非ゼロかどうかを判定しているだけでeachから何か特別な値をもらっているわけではないと解釈することが重要。
ともするとハッシュをループしたいときはこういう定型文を使うって覚えてしまいがちだけど、
ちゃんと理解して使わないと本質を見失うなぁ。
はじパはいい本ですね。
keyの順番を辞書順で出力したいとき
my %hash_list=( "hoge" => "hogeko", "fuga" => "fugao", "yamada" => "taro", "satou" => "keiko", ); # 順番ごちゃ混ぜ foreach (keys %hash_list){ print $hash_list{$_}, "\n"; } # 辞書順で出力 foreach (sort keys %hash_list){ print $hash_list{$_}, "\n"; }
6.4 ハッシュの利用法
- 6.4.1 exists関数
- 6.4.2 delete関数
# 可読性を考慮して太矢印で書きましょう my %hash = ( "hoge" => "hogeko", "fuga" => "fugao", "yamada" => "taro", "satou" => "keiko", ); print "消したい人の名前(姓)を入力てね\n"; chomp(my $name = <STDIN>); if(exists $hash{$name}){ delete $hash{$name}; print "消しておいたよ!\n"; }else{ print "そんな人いないよ!\n"; } print "Name List\n"; foreach (keys %hash) { print "$_ $hash{$_}\n"; }
- 6.4.3 ハッシュの要素を変数展開する
%hashなんて書いても意味なし。
my %hash = ( "hoge" => "hogeko", "fuga" => "fugao", "yamada" => "taro", "satou" => "keiko", ); print "Name List $hash{hoge}\n"; print "Name List %hash\n";
6.5 %ENVハッシュ
(出落ち)
6.6 練習問題
例によって勝手に色々自分で使用を色々追加する。
# 空のハッシュを用意 my %name_hash; # 複数行名前を入力してもらう print "適当に名前を入力。あえて重複して入力して下さい。\n"; print "Ctrl+Dで終了です。\n"; chomp(my @name_list = <STDIN>); foreach (@name_list){ if(exists $name_hash{$_}){ $name_hash{$_} +=1; }else{ $name_hash{$_} = 1; } } print "名前とその入力回数\n"; foreach (sort keys %name_hash){ print "$_ : $name_hash{$_} 回\n"; }
%ENVの問題が増えてた!
foreach(sort keys %ENV){ printf "%-30s : %15s\n" , $_, $ENV{$_}; }
7章 正規表現の世界
7.2 単純なパターンを使う
- 7.2.1 メタキャラクタについて
- 7.2.2 単純な量指定子
.*をガラクターって言うらしい(嘘)。
- 7.2.3 パターンをグループにまとめる
一瞬意味がわからなかったけどまあそうか。
$_ = 'Hello World!'; if (/(fred)*/) {print "Match!!\n"}; # もちろんマッチ!!
- 7.2.4 選択肢
7.3 文字クラス
- 7.3.1 文字クラスのショートカット
- 7.3.2 ショートカットの否定
7.4 練習問題
fredとwilmaってだれだよ〜
while (<>) { chomp; if (/(.*(wilma)+.*(fred)+.*)|(.*(fred)+.*(wilma)+.*)/) { print "Matched : |$`<$&>$'|\n"; }else{ print "No Match\n"; } }
次ー!
8章 正規表現によるマッチ
お、新しい項目が増えている…(第5版買ってよかった!)
8.1 m//を使ってマッチを行なう
^はキャレットと読む。
テストにはでない。
8.6 マッチ変数
- 8.6.2 キャプチャなしのカッコ
(?:hoge)とかすると良いらしい。
- 8.6.3 名前付きキャプチャ
コロンの代わりに
?
にして、
$+{laberuonamae}
で取り出せる。
後方参照は、
\g{laberunomae}
- 8.6.4 自動マッチ変数
8.7 汎用の量指定子
8.8 優先順位
- 8.8.1 優先順位の例
- 8.8.2 お楽しみはこれからだ
↑
8.9 パターンをテストするプログラム
8.10 練習問題
これはまずい。
楽しいのと奥が深いのでやばい。
ただ『詳説正規表現』は買わない!!←
while (<>) { chomp; if (/(\b\w+\b)\s+\b\1+\b/) { print "Matched : |$`<$&>$'|\n"; }else{ print "No Match\n"; } }
なーんか第5版問題違いまくり?
while(<>){ chomp; if(/\h$/){ print $`,"_",$&,"_\n"; }else{ print $_,"\n"; } }
ということで約半分終わったぞ!!!
目標は今週中に読み終わること!
ばんばります!!