スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
bash の文字列操作
# ## % %% :

ん~ まったく覚えられない。
ということでまとめました。

AA='ABCDE'; AA=${AA#AB}; echo ${AA};  # 前からマッチを削除 ## なら最長マッチ
AA='ABCDE'; AA=${AA%DE}; echo ${AA};  % 後ろからマッチを削除 %%なら最長マッチ
AA='ABCDE'; AA=${AA:2};  echo ${AA};  : 前から削除  

AA='ABCDE'; AA=${AA/AB}; echo ${AA};  てかこれでええがな。正規表現 
CDE
ABC
CDE
CDE


でも、これが使えると超便利!

oldディレクトリとnewディレクトリには、同名のファイルがたくさんあるんだけど、oldディレクトリにはその名のとおり、古いファイルが入ってて、newディレクトリには新しいファイルが入ってる。さあ、差分をとりたい! DFディレクトリに各々のファイルの比較結果を同名のファイルに書き出そうじゃないか。

ひとつだけの場合の例)
diff old/a.txt new/a.txt > DF/a.txt


forで一気に複数やる場合)
for file in old/*; do diff ${file} new/${file#old} > DF/${file#old}; done
スポンサーサイト
Java使いに贈るPerl入門
C言語erに贈るPerl入門

なんか他にも書けそうな気がしてきたので。

・クラスはパッケージ
・main関数がないのが気になるなら、 sub main { } か { } を書く。
・インスタンス変数はハッシュでOK
・perldocはjavadocに影響を与えた
・参照のようなものは、リファレンス
・Eclipseのデバッガのように変数の中身を見たければ Data::Dumper

ん~、
他にもいろいろありそうな気がする。
C言語erに贈るPerl入門
・変数は使う手前で作成
・main関数がないのが気になるなら、 sub main { } か { } を書く。
・構造体は、ハッシュでOK
・ポインタのようなものは、リファレンス

ん~、
他に必要な項目あるかなぁ?
プログラミング言語
C言語は型を強制するし、 
Javaはクラスを強制するし、
Rubyは高階関数を半強制するし、
Perlはハッシュ使うと use strict の意味ないし、
JavaScriptはデータ構造変えちゃうし、
Lispは関数を強制するし、
Haskellは変数は悪だと叫ぶし、

でもプログラミングが好き
bash の read とか すごいね
Perlから入った私は混乱しちゃったよまったく。

read 変数名 変数名 ...

って書式ですか! こりゃユカイ!

あと、 bash のリダイレクトだけど、

aaa > b.txt は aaa 1> b.txt  の略ですか
なるほどぉ!!

<< でヒアドキュメントも可能なんだ! ということでこんな書き方ができるんだ こりゃすげぇえ!

while read AAA BBB
do
 echo $AAA
 echo $BBB
done << END > b.txt
aaa bbb
ccc ddd
eee fff
END
$ cat b.txt 
aaa
bbb
ccc
ddd
eee
fff
インラインでオンザフライ
同じような処理をを見つけたときや、
なにかこのあたりはひとまとまりの意味のある処理だな
と思ったときに、関数にすることは、大切なことだ。

でもだ!でもだなぁ!!!!!!!!

関数ってのが作れないときってのがあるんだよ!!!!!
どういうときかというと、大人の事情で増やしたくないときとかだなぁ。
(いや、これは結構、納得してしかるべき理由があったりする実のところ)

そこで、インラインでオンザフライに関数を作っちゃう機構がPerlにあるんだな。
それが do。

do ブロック

という書式で最後に評価された値がかえるんだ!
しかもインラインでオンザフライにだぜ! イケテるぅ!!

my $c = do{
           my $c    = 'doからこんにちは';
           my $d    = 'doからこんばんは';
           my $flag = 1;
           $flag == 1 ? $c : $d;
         };

print $c;
doからこんにちは


でも、これって 無名関数でもできるんだ。やってみよう。
my $c = (sub{
           my $c    = 'doからこんにちは';
           my $d    = 'doからこんばんは';
           my $flag = 1;
           $flag == 1 ? $c : $d;
         })->();

print $c;

doからこんにちは

これで、みんなが大好きJavaScriptっぽくなったわけだ。ユカイユカイ。
オン ザ フライ
on the fly

プログラミング中に空中でアクロバットをかますときに使われる。

難易度C級


はじめて見たときはたいていの者が理解できない

でも誰でも使えるとってもやさしい技。コツがいる。



今日は、プログラミングにおける on the fly の話をしよう。
こいつは、空中でアクロバットがかませる すげーカッコいい技なんだ。

ここでは、オン ザ フライの簡単な例を紹介するね。
bashのスクリプトを例に出すね。 「えー bash 知らないんだけどー」って
方も我慢して。 本当にすごく簡単な例だから。

日付を表示させるだけのたった2行のソースだよ。
d=`date`
echo $d
2008年 10月27日 月曜日 23時14分16秒 JST

ほらできた。
(えーなに? 1行目に #!/bin/bash が付いてないだって?
そんなもの書かなくても、こいつは実行できるよ。早く入門書は卒業して)

変数dに、 date で取れる値をお行儀よく入れているね。結構だ。
よくできました。授業だとまさにパーフェクトな解答だ。

んーでも、つぎのようにも書けないか?
echo `date`
2008年 10月27日 月曜日 23時18分03秒 JST

ほらいけた。変数dなんて必要なかったね!

date は使いたいところで、その場で実行してあげればよかったんだ!!


お次はPerlでみてみよう。 
「えー Perlはわからない」 だって??

落ち着いて、bashより簡単だから。
次のソースは、配列の中身をただ表示してるとっても簡単な例なんだ。
use strict;

my @arr = (1, 2, 3);

for(@arr){
  print $_ . "\n";
}
1
2
3

ほら、できた。
(えーなに? 1行目に #!/usr/bin/perl が付いてないだって?
そんなもの書かなくても、こいつは実行できるよ。早く入門書は卒業するんだ!
いや その前に、Unixとかについて勉強した方がよいかもしれないぞ)


でも、さっきの echo `date` を知った僕たちには、これってなんだかまどろっこしくないかな? for の中に一気に書けたらいいと思わない?

こんな風に。
use strict;

for(1, 2, 3){
  print $_ . "\n";
}

ほら、ちゃんと動くんだ!
1
2
3


多くの大学とかでは、まず初めの言語としてC言語を学ぶんじゃないかな?
C言語は型もしっかりしてるし、スコープの勉強にもなるし、けっこういいことが学べる言語だ。多くの人がそういう意味でよく知ってるし、UnixもC言語でできてるし、みんなの共通認識になる点では大変よい。

でも、ちょっと待って! 厳格にやり過ぎてたよ。
変数は int i と宣言します。というように何度も聞かされているうちに、
僕らは、値ってのは変数にいれて使わなくちゃいけないと思い込んでしまうようになった。
それは、プログラムを習い始めた人にはとても大切なことだ。(変数ってのは値を入れて、でもってその値が変わるから、文字通り「変数」っていうんだ!って理解できる)

プログラムなんて1年や2年なんて短い期間でマスターできるってものじゃないんだよ。なんでもそうだけど、まず基本を習う、そして応用。 上達するにしたがって、どんどんやり方を変えていくものなんだ!

いつまでも、これは「おまじないです」じゃダメなんだよ!
「おまじないに」 自分で踏ん切りをつけて、いままで「おまじない」だったことを理解して、「ああ なるほど そういうことだったんだ じゃあ、それは、この場面では必要ないなぁ」って理解していくことが大切なんだ。

必要なものを必要なときにだけ使って、必要ないときには使わない
これが、できるようになると、空中でアクロバットをかませることができるようになってくるんだ。
如何にJavaScriptとPerlは似ているか
JavaScriptとPerlは、そっくりさん。
よく似てらっしゃいます。


配列をみてみよう。
JavaScript
arr = [1,2,3];

alert(arr[2]);
Perl
$arr = [1,2,3];

print $arr->[2];


ハッシュをみてみよう。
JavaScript
h = {
      A :'a',
      B :'b',
      C :'c'
    };

alert(h.A);
Perl
$h = {
       'A'=>'a',
       'B'=>'b',
       'C'=>'c'
     };

print $h->{'A'};


関数をみてみよう。
JavaScript
f = function(){ alert("Hello") };
f();
Perl
$f = sub { print 'Hello'; };
$f->();




その場で作って、その場で実行も同じようにできるよ。

配列
JavaScript
alert(([1,2,3])[2]);
Perl
print +([1,2,3])->[2];

ハッシュ
JavaScript
alert(({
        A:'a',
        B:'b',
        C:'c'
      }).A);
Perl
print +({
         'A'=>'a',
         'B'=>'b',
         'C'=>'c'
       })->{'A'};


関数
JavaScript
(function(){ alert("Hello") })();
Perl
(sub { print 'Hello'; })->();




でも、まあ構文(書き方)で似てるやつを選んだらの話で、
JavaScriptは全部ハッシュだったりとか、いろいろ作りは違うけどね。
上記の例で同じような書き方で、同じように振る舞う場合があることが、
多いのはわかってもらえると思う。


関数を作ってその場で実行は、スコープの問題を解決するために、
JavaScriptでは最近多用されまくるけど、Perlでは、その問題はないため、
使われる箇所は全然違ってくる。

結局のところ、どのタイミングで、どの箇所にどのように書くか は、
長年、その言語を読み書きしていないと見えてこない。
構文(書き方)が似てるからといって、むこうの言語と同じようなタイミングで 書けば異端児扱いになるだろう。


Perlでは、とくに意味がなければ、関数は、
$f = sub { };
ではなく、
sub f{};
にしてほしいし、

配列は、とくに意味がなければ、
@arr = (1,2,3);
としてほしいものだ。
君のプログラムスタイルを抜本的に変える方法
今から、Perlについてとても大切なことを書く。
これを理解すれば、Perl中級をいっきにぶっとばして
上級クラスの仲間入りをすることができる。

まずは、Perlの関数への引数の渡し方をみよう。

sub f {
 my ($c, $d, $e) = @_;

 print "1: $c" . "\n";
 print "2: $d" . "\n";
 print "3: $e" . "\n";
}

my $x = 10;
my $y = 9;
my $z = 8;

f($x, $y, $z);

実に簡単な例だ。
これは実によくできている。
結果:
1: 10
2: 9
3: 8


では、次のように配列を渡すとどうなるだろう?
sub f {
 my ($c, $d, @e) = @_;

 print "1: $c" . "\n";
 print "2: $d" . "\n";
 print "3: @e" . "\n";
}

$x = 10;
$y = 9;
@z = (8,7,6);

f($x, $y, @z);

よかった!うまくいった!!
結果:
1: 10
2: 9
3: 8 7 6

気分をよくしたので、もうひとつ引数を渡してみることにしよう。
sub f {
 my ($c, $d, @e, $f) = @_;

 print "1: $c" . "\n";
 print "2: $d" . "\n";
 print "3: @e" . "\n";
 print "4: $f" . "\n";
}

$x = 10;
$y = 9;
@z = (8,7,6);
$w = 5;

f($x, $y, @z, $w);

なんてこった!!
@e に、$w をかっさわれてしまった!!
結果:
1: 10
2: 9
3: 8 7 6 5
4:  

どうすればいいんだと、頭をかかえて
1週間を過ごすかわりに次のようにしてみるといい。

sub f {
 my ($c, $d, $e, $f) = @_;

 print "1: $c" . "\n";
 print "2: $d" . "\n";
 print "3: @$e" . "\n";
 print "4: $f" . "\n";
}

$x = 10;
$y = 9;
@z = (8,7,6);
$w = 5;

f($x, $y, \@z, $w);

結果:
1: 10
2: 9
3: 8 7 6
4: 5

リファレンス渡しにしてあげればいいんだ。
リファレンスってのは、変数を指し示すスカラーなモノなんだ。
スカラーっていうのは、「ただひとつ」って意味。

$ref = \@c

とすれば、配列というたくさん値を持ったモノを、
ただひとつの変数、$ref で持てるんだ! こりゃユカイ!!


ここで、関数がハッシュを受け取ることを考える。
ハッシュも配列と同じで、たくさんの値を持っているので、
さっきみたいに、かっさわれないようにリファレンス渡しにしてやる必要がある。

さあ、「18以上じゃないとダメ」と大人な返事をする関数を作ってみよう。
※とりあえず、第2引数は与えるものが思いつかなかったので顔文字にしておいた。

sub f {
 my ($c, $d) = @_;

 if( $$c{'age'} >= 18 ){
   print "18歳以上なのでOK $d";
 }else{
   print "君にはまだ早いよぉ $d";
 }
}

my $x = '(^_^)';
%y = ( 'age' => 18 );

f(\%y, $x);

結果:
18歳以上なのでOK (^_^)


さて、なんでこんな例を出したんだろう?
あ、そうだ、次のことを言いたかったからなんだ。
18歳以上じゃないとできないことがある.....

ではなくて、

ハッシュをもらってそのキーと値から関数の挙動を変える
ということをしているCPANモジュールが結構存在するんだ。

そこで、さっきみたいにこんなソースを書くことになるだろう。

sub f {
 my ($c) = @_;

 if( $$c{'flag'} == 1 ){
   print "OK";
 }else{
   print "NG";
 }
}

my %c = ( 'flag' => 1 );
f(\%c);


ナンセンス!!!!!!!
その%cって本当に必要なの??

その変数名を考えるのに時間と脳細胞を無駄にしてませんか???

また、あとでソースを読むときも、
短期記憶に覚えておかないといけない変数名が増えてしまいます。
これくらいのソースならいいが1万行からなるソースを読むときだと考えたらどうだろう??

それだけじゃない、%cがソースの中でどこで使われてるか調査する必要があって、
このf(\%c)ってところ1カ所だけだったとわかったときの、俺の作業時間っていったい.... って気持ちがわかる??
はは、調査なんて grep すればいいじゃないかぁ! だって??
スコープが違えば、同じ名前を使っても問題ないんじゃなかったけ!??

この書き方は、
目玉焼きを作るのに、卵を割っていきなりフライパンに入れずに、
一度、容器に入れてから慎重にフライパンに移すようなものなんだ!!
そんな無駄なことする人っている???

いきなりフライパンに入れてしまえばいいんだ!
こんな風にね。
sub f {
 my ($c) = @_;

 if( $$c{'flag'} == 1 ){
   print "OK";
 }else{
   print "NG";
 }
}

f({'flag'=>1});


これは、ハッシュに名前をつけてないから、
無名ハッシュって呼ばれる方法なんだ。
この無名ハッシュはリファレンスなんだ。
だから、使い捨ての変数を用意する必要なんていらなんいんだ。
他にも、Perlでは、
無名配列に、無名関数を使えるんだ!

この無名シリーズを使えるようになると、
今までのプログラムスタイルはなんだったんだと思えるぐらい
革命的なソースが書けるようになるぞ。


無名関数については、
つぎの資料がよい。
君のプログラミング言語で、これ、できる?

リンク先はJavaScriptでの例ですが、そうです。同じように、Perlでも可能なのです。
Perlの systemとバッククォートの違い
つぎのソースを実行すると、
my $c = system('echo a');
print $c;

結果:
a
0
となるんだ。

では、つぎのソースはどうだろう。
my $c = `echo a`;
print $c;

結果:
a


つまり、 system は外部プログラムを実行させて、戻り値は、そのプログラムが成功したかどうかを返すんだ。

バッククォートの方は、 外部プログラムの結果を返してくれるんだ。
僕の .bashrc
僕の .bashrc に、 次のような箇所がある。

today (){
  perl -e 'use POSIX 'strftime';
           $dir_name = strftime("%Y%m%d", localtime);
           mkdir $dir_name or die $!;'
}

cd_today (){
  D=`date +%Y%m%d`;
  cd ./$D;
}

これでも動くけど、本当は perl -e のところは1行で書いてある。

today () {
 perl -e ' プログラム '
}

って感じで。
で、これを書いておくとなにが便利かというと!
$ today

今いるディレクトリで today と打てば、そのディレクトリに、
今日の日付のディレクトリ(例:20081026) を作ってくれるんだ。

$ cd_today

とすれば、作ったディレクトリに移動してくれるよ。
僕は、いつも同じディレクトリの下に、今日の日付のディレクトリをを作るので、
cd_today のパスは 「cd いつものディレクトリ/$D」 となっていて、
どこからでも、今日の作業ディレクトリに移動できるようにしてある。


さて、こうやって、順調に毎日作業をして、
次の月がやってきたとする。 9月から10月になったときとかだね。

そうすると、ディレクトリが 9月の日付のでいっぱいになってしまう。
そこで、ひとつのディレクトリに移動させたくなるんだ。

「そうだ! 2008年9月につくったディレクトリは、 xx_200809 という
ディレクトリをつくってそこに移動させよう!!」

これを 行うのがつぎの作業だ。

mkdir xx_200809
cp -r 200809?? xx_200809/
ls -R xx_200809
rm -ir 200809??


cp -r でリカーシブルにディレクトリを移動させているよ。
さらに ??  に気づいた?
これで、任意の2文字に展開されるから
20080901 とか 20080930 とかにマッチしてくれて、
いっきに cp できるってわけ。

ls -R でリカーシブルに、
ちゃんとディレクトリが cp できているか確かめているよ。

そしたら、
rm -ir で元のディレクトリを消そう。
-i は消していいですか? と聞いてくれるオプションだ。


みなさんからも、便利なスクリプト教えていただけるとうれしいなぁ。
ハイパー上級Perl検定
「みんなの検定」に、
ハイパー上級Perl検定 というのを作りました。

よかったら、ぜひやってみてください。










※ 間違い等ありましたら、知らせていただけると幸いです。
「みんなの検定」にPerlの問題を作成しました
完全に、個人的趣味で、
「みんなの検定」に、
Perlの問題を作りました。

解答の解説を充実させたつもりですので、
よかったらやってみてください。
世の中にPerlプログラマが一人でも増えたらよいなぁ


ハマりやすいところから、初学者が学んでおかないといけないところ。
マニアックな知識まで。取り揃えてみました。

以下のボタンで、難易度別に問題を絞りこめます

 ※2008/12/30に一部、合格基準を引き下げました



※ 間違い等ありましたら、知らせていただけると幸いです。
※ 「やさしいPerl検定(8)初級」 の第4問は、問題文が途中で消えてしまうようです。
やさしいPerl検定(8)初級
↑こちらのリンクからやってくださると、問題文は消えていないようです(お手数をおかけします)。
ポインター解析
http://bingobingobingo.blog49.fc2.com/blog-entry-888.html
C言語で、変数の中身簡単に出力してくれるのないかなぁ。
という話ですが、関連ワード(?)として、「ポインター解析」なるものを教えてもらった。
なるほど、「型推論」とかの話と結びつくのかな。
「型推論」なんて聞いたことあるレベルぐらいだが。
log4perl
[参考資料]
1. http://search.cpan.org/~mschilli/Log-Log4perl-1.18/lib/Log/Log4perl.pm
2. http://search.cpan.org/~mschilli/Log-Log4perl-1.18/lib/Log/Log4perl/Appender/File.pm
3. http://search.cpan.org/~mschilli/Log-Log4perl-1.18/lib/Log/Log4perl/Layout/PatternLayout.pm
4 . http://codezine.jp/article/detail/152?p=1

アペンダーの意味がわからなかったが、参考資料4より納得できた。
引用:

アペンダーとはログ出力先のことです



hoge.properties
# log4perl.logger.カテゴリー名(任意)    = ログレベル, アペンダー名(任意)
log4perl.logger.bingo.file              = INFO, FOO
log4perl.logger.bingo.screen            = INFO, Screen

# アペンダーの実装
log4perl.appender.FOO                   = Log::Log4perl::Appender::File
log4perl.appender.FOO.filename          = \ 
                  sub { "./foo_" . strftime("%Y%m%d", localtime) . ".log" }
log4perl.appender.FOO.layout            = PatternLayout
log4perl.appender.FOO.layout.ConversionPattern = %d --%p-- %m %L %n 

log4perl.appender.Screen         = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr  = 0
log4perl.appender.Screen.layout = Log::Log4perl::Layout::SimpleLayout


上記の設定の場合で、出力先にファイルを使うとき
use Log::Log4perl;
use POSIX 'strftime';

# ロガーの設定ファイルを指定
Log::Log4perl::init('./hoge.properties');

# ロガーのカテゴリーを指定
$log = Log::Log4perl->get_logger('bingo::file');

$log->info("aaaaa");


上記の設定の場合で、出力先にターミナルを使うとき
use Log::Log4perl;

# ロガーの設定ファイルを指定
Log::Log4perl::init('./hoge.properties');

# ロガーのカテゴリーを指定
$log = Log::Log4perl->get_logger('bingo::screen');

$log->info("aaaaa");
設定ファイルを持つと超便利
設定ファイルに定数などを持っておくと便利ですねぇ。
もしくは、状況によりしだい値が変わるものとかね。

Perlには、Config::Simple なんてのがありますので、これを使いましょう。
使い方は、ソースを見た方が早いです。

hoge.ini
[bar]
HOGE       = "hoge"
FOO        = "foo"

[xyzz]
SOME       = "some", "any"


hoge.pl
use Config::Simple '-strict';

$c = Config::Simple->new('./hoge.ini')->vars()
       or die Config::Simple->error();

print $c->{'bar.HOGE'} . "\n";
print $c->{'bar.FOO'}  . "\n";

print "\n";

print $_ . "\n" for @{$c->{'xyzz.SOME'}};

結果:
hoge
foo

some
any
C++ の typeid すごくねぇ??!!!!!!
http://bingobingobingo.blog49.fc2.com/blog-entry-885.html
のC言語版ってないのかなぁ?
gdb は起動させるのめんどくさそうだし....
さらに gdb ではログに吐けないじゃん!
$logger->(Dumper $hoge);
的な感じで(知識不足?)

ちょっと調べてみて、C++ にtypeid なるものがあるのがわかった。
#include <iostream>
#include <typeinfo>
using namespace std;

int main(void){
  int i;
  int *p;
  int **pp;
  double ***ppp;
  int a[3][3];

  cout << typeid(i).name()   << '\n';
  cout << typeid(p).name()   << '\n';
  cout << typeid(pp).name()  << '\n';
  cout << typeid(ppp).name() << '\n';
  cout << typeid(a).name()   << '\n';
}

結果:
i
Pi
PPi
PPPd
A3_A3_i

これで、少しは幸せになれるのだろうか。
でかいなぁ
でかいなぁ。

でかいところでは、そのやりかたでやらんと、
いけないんだろうな。

Joel on Software
はやっぱり面白いなぁ。
クラス?? インスタンス? なにそれ おいしいの?
次の例は、それぞれオブジェクト指向と言われるやつだ。

パッケージを使ったやり方:
use strict;

my $o = Hoge->new();
$o->say();

package Hoge;
sub new { bless {}, shift; }
sub say { print 'なにか言う' . "\n"; }


プロトタイプに入れてけばOKというやり方:
Array.prototype.say = function(){ alert("なにか言う") };
o = new Array();
o.say();

プロトタイプの方なんて、もはや継承ってなに?
っと言いたくなるレベル。

JavaScriptで次のソースを見てみると、さらに「ひょぇーー」と驚くことになる。
function bingo_nakanishi(){};

for( i in window ){
 console.log(i);
}

出力された値に、bingo_nakanishi がいるではないか!!?
これをJavaScriptの言葉で汚染と呼ぶ。
デバッグのときに変数の中身みたいときありますよね
デバッグのときに変数の中身みたいときありますよね。
ありますよね。ありますとも。

Perl  print Dumper $hoge
Ruby  p hoge
PHP  print_r($hoge)

これでバッチリ。
Perlerは、
Javaからは例外処理の仕方を学べる。

JavaScriptからは、驚くほど柔軟な書き方を学べる。
JavaScriptとPerlは恐ろしく似ている。
最近は、JavaScriptをPerlに翻訳することができるようになってきた。
サラリーマン
サラリーマンには酷な書籍とかってあるよね「ハッカーと画家」とかがそれ。

そんなサラリーマンでもたまにエキサイトしちゃうことがあるんだ。

ちょっと自分が作ったものを全社に宣伝できる機会があったんだ。

宣伝したのは、もう2ヶ月ぐらい前になると思うんだけど、ついこないだ、使わせてほしいとまったく会ったこともない方から連絡が入ったんだ。エンジニアとしてこんな喜び他にある?
Javaのインタフェース
Javaのインタフェースについてだ。
Map, Set, List とかは、インタフェースだね。
で、こいつらを実装してるクラスがあるんだが、そんなことは、あまり考えないで、
Map が使いたいなぁ と思ったら、
Map map = new ○○(); と書いておけば大抵OK。

具体例を見てみよう。
ここに、君を作るぞ。そうだ君だ。
interface You {
	  void say();
}

これで君は、何か言えること(sayできる)だけは、決定したんだ。
だが、まだ君がなにを言える(sayできる)かは、決まっていない。

君は、生まれたばかりだとしよう。だから、赤ちゃんの君、BabyYouを作ろうじゃないか。
class BabyYou implements You{
	public void say(){ System.out.println("ばぶばぶ"); }
}

よし、できた。これで準備は万端。君のしゃべる声が聞けるんだ。
public class Main {
	public static void main(String[] args) {
		You you = new BabyYou();
		you.say();
	}
}

君をYouと宣言してるところに注意だ。BabyYouとは宣言してないんだ。
なんでかって? それは君が成長することを見越しているからなんだ。

大人になった君を作ろう。そうだ、君は大人になったんだ。大人な君、AdultYouを作ろう。
class AdultYou implements You{
	public void say(){ System.out.println("大人だ! 大人になったよ"); }
}

よしできた。ついに大人になった君の声を聞いてみようじゃないか。
public class Main {
	public static void main(String[] args) {
		You you = new AdultYou();
		you.say();
	}
}

どうだい? You で宣言していたおかげで、 new BabyYou() のところを、
new AdultYou() に変えるだけで、すんだんだ。
これで、20年先のソースでも改修は、簡単!ってわけさ。

しかし、最後に言っておかないといけないのは、僕はJavaに詳しくないってことさ。
Javaには無名クラスというのがあってだね
Javaには無名クラスというのがあってだね。
上位のクラスをその場で実装して生成するみたいなのができるわけだ。
んじゃ、クラスなんて作らなくても、Objectを継承するかたちで、無名クラスいっぱーい書けばいいじゃん と思ったら、Objectが持ってるメソッドしか実装できないではないか。クラスが型ですからね。

ということで、こういうので我慢する。
私がJava界隈の人間でなくても、もしこういったソースを業務でみたら、どうしようもない怒りを覚えるだろうが。
public class Hoge {
  public static void main(String[] args){
 
	  new Object(){ 
		  public String toString(){ System.out.println("こんにちは");
	      return null; }
	  }.toString();
  }
}
間違いを探しなさい
次のソースは間違いだ。
use strict;

my $c, $d;

$d = 1;

print $c;


正解は、
use strict;

my ($c, $d);

$d = 1;

print $c;




次のソースはなにか勘違いをしている。
use strict;

my %h = ('name', 'age');

$h{'name'} = 'nakanishi';
$h{'age'}  = 10;


正解は、
use strict;

my %h = ('name' => '',
         'age'  => '');

$h{'name'} = 'nakanishi';
$h{'age'}  = 10;

この場合は、
use strict;

my %h = ('name' => 'nakanishi',
         'age'  => 10);

の方が自然であるが。
交互にスレッドを動かす方法
んー Javaのことは よくわからんなぁ.......
notifyAll(); って2カ所も書いてるのがダサイのだが、
こういものなのかなぁ
public class Hoge {
  public static void main(String[] args){
	Foo f = new Foo();
	new T(f, "A").start();
	new T(f, "B").start();
  }
}

class Foo{
	public void p(String name){
	  for(int i=0;i<10;i++){
		synchronized(this){
		  System.out.println(name + i);
		  notifyAll();
		  try {
			wait();
		  } catch (InterruptedException e) {
			e.printStackTrace();
		  }
		  notifyAll();
		}
	  }
	}
}

class T extends Thread{
	Foo f;
	String name;
	
	T(Foo f, String name){
		this.f    = f;
		this.name = name;
	}
	
	public void run(){
		f.p(name);
	}
}
リファレンスをデリファレンスする方法
さて、C言語でポインタを 元に戻して使う方法を理解したのなら、
Perlのリファレンスを元に戻す方法なんて超簡単!!

$c = 1;
$ref = \$c;
print $$ref;


Perlはこんな感じで元に戻すわけですが、
上の例では、 $c に \ を1つ付けてリファレンスを取得してます。
\ を一つ付けてリファレンスしたわけですから、 $ を一つ付けて
$$ref で元にもどるわけです。

\ を 5つ付けた
$c = 1;
$ref = \\\\\$c;
print $$$$$$ref;

なら、 $ を5つ付ければいい。ただこれだけ。

配列だったら、
c = (1,2);
$ref = \\\\\@c;
print @$$$$$ref;

という感じ。
一番左の記号が、もとの変数が何だったか 示しているのです。

\ 5個でデリファレンスした場合、

配列だったら、   (@ + $4個) + $ref です。
スカラーだったら、 ($ + $4個) + $ref です。
ハッシュだったら、 (% + $4個) + $ref です。

「\と同じだけの$で元にもどす。ただし、最後の記号はもとの変数に合わせる」

これだけ覚えれば 実に簡単にリファレンスを使いこなせます。
C言語のポインタを使うときの方法
C言語のポインタに関して。

ポインタの宣言は,
int *p;
int **pp;
int ***ppp;
みたいに * を使います。

これを使うときは、

printf("%d\n", *p);
printf("%d\n", **pp);
printf("%d\n", ***ppp);

というように、 * を使って元に戻すわけです。

つまりですね。宣言のときの形を使えば元に戻るわけです。
p は * ひとつで宣言してますよねだからint に戻すには、 *p
pp は * ふたつで宣言してますよねだから int に戻すには、 **pp
ppp は * みっつで宣言してますよねだから int に戻すには、 ***ppp

さて、ここまでのをソースでみてみましょう。
include <stdio.h>

int main(void){

  int i=20;
  int *p;
  int **pp;
  int ***ppp;

  p    = &i;
  pp   = &p;
  ppp  = &pp;

  printf("%d\n", *p);
  printf("%d\n", **pp);
  printf("%d\n", ***ppp);
}


こんな感じですね。

さて、使うときに * を何個付ければ元に戻るかなんですが、もうひとつ別の覚え方があります。

上のソースの例では、
p は i に &が一つ付いた &i です。

pp は &p ですね。
ということは、 i に&が2つついた &&i と同じな訳です。(pは &i ですから)

ppp は &pp です。
ということは、 i に&がt3つついた &&&i と同じな訳です。

つまりもとに 戻すには、 &と同じ数だけ * を付ければいいのです。
Perlでは、変数名に $a と $b は使うな!
use strict は ご存知ですよね。
変数を my とかで宣言してないと、

「おいおい、オメー 何考えとんじゃ」

と怒ってくれるあいつです。

簡単にみてみましょうか。
use strict;

$c = 'hoge'; # my 忘れてますがな

これを実行しようとすると、

Global symbol "$c" requires explicit package name

てな感じで怒ってくれます。

では、次のソースはどうでしょうか?
$c を $a に変えてみました。
use strict;

$a = 'hoge'; # my 忘れてますがな

これは、無事に(?)実行できてしまうんですね。

この理由はなぜなんでしょう?
それは、 sort があるからです。

こんな感じ、
http://www.rfs.jp/sb/perl/05/sort.html
このsort で $a と $b を使うわけです。こいつらに my を書いてたらうっとうしい。
だから、$a と $b は、use strict の対象外なのです。 変数名は$c から始めましょう(ま、なんでもいいんですが)
Perlのサブルーチンの書き方 ちょっとだけ紹介
Perlのサブルーチン(関数)を自信をもって書けるようになるには、たいへん長い時間を要しました。

「なに、この言語 ムッキー!!」

ってなるようなハマりどころがいっぱいです。たかが、サブルーチン呼ぶだけなのにぃ。

さて、まず、サブルーチンの作り方から紹介します。

sub f { }

です。 これで、fという名前のサブルーチンを作りました。
つまり、

sub サブルーチン名 { }

です。

C言語などの他の言語につられて、

sub f() { }

と、fの後ろに() を書いてもエラーにはなりませんが、スマートなPerlプログラムを目指すなら、()は不要ですよ~ ()は関数呼び出しのときに使いましょう。

「えー サブルーチンの名前の後に()要らないなんて、おかしないか?」

と思うかもしれませんね。
では、サブルーチンの名前の後の()は、他の言語ではどのように使われているでしょうか?
そうです。f( a, b, c) { } こんな感じで、引数をもらう為に使うんですよね。

Perlでは、引数は、特殊変数 @_ に入りますよね。だから、わざわざ引数をうけとるための( ) なんて不要なわけです。



他にも書きたいこといっぱいあるんだけど、今回はここまで。
ブログ検索

プロフィール

ビンゴ中西
Perlが好きである。
プログラミング言語のほとんどは独学。独学の過程で多くのプログラム仲間にも色々教わりました。

FC2カウンター

カレンダー

09 | 2008/10 | 11
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

ブロとも申請フォーム

この人とブロともになる

| ホーム | 次のページ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。