categories: perl

how to refer complex perl variables

just for my memo… Here is sample code.

#!/usr/bin/perl
use Data::Dumper;

my $arg;
$arg = {'first' => 'aaa',
    'second' => 'bbb'};
print Dumper($arg);
print $arg->{'first'} . "\n"; #print 'aaa'

undef($arg);

my $arg;
$arg->{'1'} = {'1-1' => 'value1',
        '1-2' => 'value2'};
$arg->{'2'} = {'2-1' => 'value3',
        '2-2' => 'value4'};
print Dumper($arg);
print $arg->{'1'}->{'1-2'} . "\n"; #print 'value2'
print $arg->{'2'}->{'2-2'} . "\n"; #print 'value4'
print $arg->{'2'}->{'2-3'} . "\n"; #print NULL

ustreamの録画スクリプトを公開します

公益に資すると思いますのでustreamを見ることができない人、インターネット環境に容易にアクセスできない方に映像を届けることができるように、ustreamの録画スクリプトを公開します。 ダウンロード当初の目的を果たしたと思いますのでダウンロードは停止しました。欲しい方はメールでご連絡ください 使用するためには以下のperlモジュールをインストールしてください。 * utf8 * Encode * Data::Dumper * LWP::Simple また以下のコマンドを使用できるようにしてください * rtmpdump 内部でuStreamのDeveloper IDに紐づくAPI keyが入っていますが、そのまま利用いただいて構いません。ただしDeveloper APIの利用は1日に5000回に制限されていますので、可能な限りDeveloper登録をして、API keyを取得し、スクリプト内部のAPI keyを書き換えてください。 uStreamのDeveloper登録は以下のURLから行うことができます http://developer.ustream.tv/home スクリプトについてご不明な点は私までメールいただければできる限り対応します。

今日は投票スクリプトを作成した

誰に言われるわけでもなく。 ドキュメント含め12時間で動くものができた。やっぱperlすげえますます気に入った!あと仮想サーバも!既存の環境に手を入れずにすぐにクラサバ環境作れる!

今日はハッシュの配列について勉強した

perlの中に出てくる”->“というのが何を意味しているのか、とか。リファレンスを展開(というのかどうかよくわかんないけど)しているのね。なるほど。 例えば $VAR1 = [ { ‘foo’ => ‘bar’ } ] というデータがあったら、 $var2 = $VAR1->[0]->{foo} とすると、$var2には’bar’が入る。おおっ!なんかわかった感すげぇ!

ファイルの行数を数えるにはjoinするよりwhileで回した方が速い

クックブックに書いてあっても試さざるを得ない!900行くらいのテキストファイルを読んでみる。 join使った場合:0.01533sec whileで回した場合:0.001334sec おお。10倍も違う。そういえばPCでは10ms以下は信用できないって話があったような気がするけど・・・。まぁいいか。

iphone用に動画をffmpegでエンコードする/その3

とりあえずコマンド打つのがめんどくさいのでスクリプト組んでみた。画面サイズの最適化も入れてみた。 何をやっているのか俺は。 #!/usr/bin/perl -w use strict; my $infile; my $outfile; my $defwidth = 480; my $defheight = 272; my $owidth; my $oheight; $infile = $ARGV[0]; if(!($infile)) { print “USAGE: $0 \n”; exit(1); }elsif($infile eq “”){ print “USAGE: $0 \n”; exit(1); }else{ chomp($infile); $outfile = $infile . “.mp4”; } system(“/usr/bin/ffmpeg -i \“$infile\” 2¥> \“$infile.info\“”); my $ssize; my $swidth; my $sheight; open(FH, “$infile.info”); while(){ my $line = $_; chomp($line); my @buf = split(/\s+/, $line); if($buf[3] eq “Video:“) { $ssize = $buf[6]; $swidth = substr($ssize, 0, index($ssize,“x”)); $sheight = substr($ssize, index($ssize,“x”)+1); chop($sheight); my $ratio = $swidth / $defwidth; $owidth = 480; $oheight = int($sheight / $ratio); } } close(FH); if(!($oheight)) { print “Source image doesnot recognized. Exitting.\n”; unlink(“$infile.info”); exit(1); } system(“/usr/bin/ffmpeg -threads 4 -i \“$infile\” -r 29.97 -vcodec libx264 -s ${owidth}x${oheight} -flags +loop -cmp +chroma -deblockalpha 0 -deblockbeta 0 -crf 24 -bt 256k -refs 1 -coder 0 -me umh -me_range 16 -subq 5 -partitions +parti4x4+parti8x8+partp8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 128k -ar 48000 -ac 2 \“$outfile\“”); unlink(“$infile.info”); exit(0);

2次元以上のハッシュ配列のコピーに注意!

2次元以上のハッシュ配列の場合、要素名で示されるのは値ではなくリファレンスであるため、別のハッシュ配列にコピーしてもそのリファレンスがコピーされることになる。従って別のハッシュ配列にコピーしたと思ってコピー先の値を変更すると、同じリファレンスを持つ元のハッシュ配列の値も変更されてしまうことになる。 あー日本語じゃ説明しづらい!以下が再現コード! #!/usr/bin/perl -w use strict; my $var; my $varN; my @ar; my @arN; my %hs; my %hsN; my %dhs; my %dhsN; $var = “aaa”; $varN = $var; $varN = “bbb”; my $x = \$var; my $y = \$varN; print “—Output of Variable\n”; print “$var\n”; print “$x\n”; print “$varN\n”; print “$y\n”; @ar[0] = “aaa”; @arN = @ar; @arN[0] = “bbb”; my $i = \@ar; my $j = \@arN; print “—Output of Array\n”; print “@ar[0]\n”; print “$i\n”; print “@arN[0]\n”; print “$j\n”; $hs{‘var1’} = “aaa”; %hsN = %hs; $hsN{‘var1’} = “bbb”; my $a = \$hs{‘var1’}; my $b = \$hsN{‘var1’}; print “—Output of Hash array(Single Dimension)\n”; print “$hs{‘var1’}\n”; print “$a\n”; print “$hsN{‘var1’}\n”; print “$b\n”; $dhs{‘var1’}{‘var2’} = “aaa”; %dhsN = %dhs; $dhsN{‘var1’}{‘var2’} = “bbb”; my $c = \$dhs{‘var1’}{‘var2’}; my $d = \$dhsN{‘var1’}{‘var2’}; print “—Output of Hash array(Double Dimension)\n”; print “$dhs{‘var1’}{‘var2’}\n”; print “$c\n”; print “$dhsN{‘var1’}{‘var2’}\n”; print “$d\n”; そして出力はこんな漢字! —Output of Variable aaa SCALAR(0x87130ac) bbb SCALAR(0x87130cc) —Output of Array aaa ARRAY(0x871311c) bbb ARRAY(0x87130fc) —Output of Hash array(Single Dimension) aaa SCALAR(0x871322c) bbb SCALAR(0x87139cc) —Output of Hash array(Double Dimension) bbb SCALAR(0x86f97a4) bbb SCALAR(0x86f97a4) うわーこれはわからんわー。gnview直さなきゃ〜・・・。

スレッド間の標準出力をマージする

STDERRだとあまりいい感じじゃなかったので。 最初STDERR使って書いた。こんな感じ。 #!/usr/bin/perl -w use utf8; use strict; use threads; use threads::shared; my $t1v = threads->create(‘t1’); my $t2v = threads->create(‘t2’); while(1) { print STDERR “m”; threads->yield(); } $t1v->join; $t2v->join; sub t1 { while(1) { print STDERR “1”; threads->yield(); } } sub t2 { while(1) { print STDERR “2”; threads->yield(); } } 出力がイマイチ。で、こんな感じで書いてみた。 #!/usr/bin/perl -w use utf8; use strict; use threads; use threads::shared; $|=1; my $t1v = threads->create(‘t1’); my $t2v = threads->create(‘t2’); while(1) { print “m”; threads->yield(); } $t1v->join; $t2v->join; sub t1 { while(1) { print “1”; threads->yield(); } } sub t2 { while(1) { print “2”; threads->yield(); } } これでイイ感じ!自分が思っていた形になった。なぜかSTDERR使うよりもこっちのほうがいいんだよなぁ・・・なんでだろ。デバッグもしやすい!

skypeAPIでメッセージを送る

同じように相手にメッセージを送ってみる #!/usr/bin/perl use strict; use warnings; use Net::DBus; my $target = “<相手のID>“; my $mesbody = “chat message from SkypeAPITest.pl”; my $bus = Net::DBus->session; my $hal = $bus->get_service(“com.Skype.API”); my $manager = $hal->get_object(“/com/Skype”); my $res = $manager->Invoke(“NAME MYTEST”); print “$res\n”; if($res ne “OK”) { print “ERROR: $res\n”; exit(1); } $res = $manager->Invoke(“PROTOCOL 5”); print “$res\n”; $res = $manager->Invoke(“CHAT CREATE $target”); print “$res\n”; my $sute; my $chatid; ($sute, $chatid, $sute, $sute) = split(/\s+/, $res); my $com = “CHATMESSAGE ” . $chatid . “ ” . $mesbody; $res = $manager->Invoke($com); print “$res\n”; で実行すると相手にメッセージが届く。おーっ!

skypeAPIを使ってみる

http://www.naney.org/diki/d/2008-02-25.html を参考に。特にモジュールが必要というわけではないのね。D-Busで通信するのか。常時Skypeが上がってないとダメなんだなー。常時ログインしてないとだめなのか?