最近、見始めたサイトです。英語圏のPerl関連のニュースがまとまってていい感じです。
advent calendar 2013も始まりました。
新人女子プログラマの書いたコードを直すだけの簡単なお仕事です!|paizaオンラインハッカソンVol.1を、やってみました。
hirontさん、ある意味凄いコードですね。新人の私でもそうそうこんなコードかけませんよ。。
E判定より
hirontさん、凄いコードですねっ!!私にはこんな効率のいいコード書けませんっ!
S判定より
野田s……涙拭いてもいいですか。
あなたがLispを無視することができない理由より、Perlでは構文解析が必要とのことだったので、素のPerlで書けるか試してみる。
use 5.016;
use warnings;
package _Alias;
sub TIESCALAR { bless \(my $dmy = \($_[1])), $_[0] }
sub FETCH { ${${$_[0]}} }
sub STORE { ${${$_[0]}} = $_[1] }
package main;
sub args {
my @list = map{ \$_ } @_;
return sub {
foreach(@list){
tie ${$_}, '_Alias' => shift();
}
};
}
sub with {
my ($methods, $hash, $f) = @_;
sub{
foreach(@{$methods}){
tie $_[@_], '_Alias' => $hash->{$_};
}
goto $f;
}->();
}
my $me = { name => "foobar", age => 26 };
with([qw(age)] => $me, sub{
args(my $age)->(@_);
$age++;
});
with([qw(name age)] => $me, sub{
args(my ($name, $age))->(@_);
printf("I'm %s. %d years old.\n", $name, $age);
});
書けない事はないけど……という感じです。
feedlyをマガジンタイプで表示しているとき、Skipが押しにくかったので、Stylishで改善してみる。
@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document domain("feedly.com") {
div.metadata {
overflow: visible !important;
}
span.wikiBar {
display: block;
visibility: visible !important;
font-weight: bolder;
font-size: 120%;
}
span.wikiBar > span {
display: inline-block;
padding: 0.2em;
}
}
use Socket;
my $port = 50001;
my $servaddr = sockaddr_in($port, INADDR_ANY);
my $proto = getprotobyname('udp');
socket(my $sock, AF_INET, SOCK_DGRAM, $proto) or die $!;
bind($sock, $servaddr) or die $!;
my $max_line = 4096;
while(1){
my $cliaddr = recv($sock, my $message, $max_line, 0) or die $!;
(my $mesg = $message) =~ s/\r?\n//;
send($sock, qq{You said:"$mesg"\n}, 0, $cliaddr) or die $!;
}
参照: W. Richard Stevens,1998,UNIX NETWORK PROGRAMMING Volume1 SecondEdition,Prentice Hall,W・リチャード・スティーブンス 篠田 陽一(訳),1999,UNIXネットワークプログラミング第2版 Vol.1,ピアソン・エデュケーション,p.208
package _MyServer;
use parent 'Net::Server';
sub process_request {
my $self = shift;
my $prop = $self->{server};
(my $message = $prop->{udp_data}) =~ s/\r?\n//;
$prop->{client}->send(qq{You said:"$message"\n}, 0);
}
package main;
_MyServer->new->run(port => ":50001/udp");
参照: http://cpansearch.perl.org/src/RHANDOM/Net-Server-2.007/examples/udp_server.pl
use IO::Socket::INET;
my $server = IO::Socket::INET->new(
LocalPort => 50001,
Proto => 'udp',
) or die $!;
my $max_line = 4096;
while($server->recv(my $message, $max_line, 0)){
(my $mesg = $message) =~ s/\r?\n//;
$server->send(qq{You said:"$mesg"\n}) or die $!;
}
参照: Tom Christiansen and Nathan Torkington,1998,Perl Cookbook,O'Reilly,トム・クリスチャンセン ネイザン・トーキントン 田和 勝(訳),2001,Perlクックブック,オライリージャパン,p.629
use AnyEvent;
use AnyEvent::Handle::UDP;
my $udp_server = AnyEvent::Handle::UDP->new(
bind => ['0.0.0.0', 50001],
on_recv => sub{
my ($message, $ae_handle, $cliaddr) = @_;
(my $mesg = $message) =~ s/\r?\n//;
$ae_handle->push_send(qq{You said:"$mesg"\n}, $cliaddr);
}
);
my $condvar = AnyEvent->condvar;
$condvar->recv;
参照: http://cpansearch.perl.org/src/LEONT/AnyEvent-Handle-UDP-0.043/examples/anyevent-udp-server.pl
日本語環境では、mode con が返す結果が日本語にローカライズされていて動作しなかったので、修正してみました。牛刀をもって鶏を割く嫌いがありますが。
... @REM Save current character set for /F "usebackq tokens=2 delims=:" %%C in (`chcp`) do set CHAR_SET=%%C chcp 437 @REM Detect the width of the console for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do set CONSOLE_WIDTH=%%W @REM Restore current character set chcp %CHAR_SET% > NUL ...
読了しました。とても読みやすかったです。
エンジニアリングの一つの定義は、だれでも1ドルでできることを、10セントで行うことである。反復を後の段階まで先延ばしすることは、だれでも1ドルでできることを、2ドルで行うことである。Fred Brooksは「1つ捨てるつもりで。どうせ捨てることになるのだから」とアドバイスしている(Brooks 1995)。ソフトウェアエンジニアリングの秘訣は、使い捨てになる部分をできるだけ時間をかけずに安価に作成することである。それが、早い段階での反復のポイントなのだ。
CODE COMPLETE 第二版 下,p467より引用
私がPerlを使う理由の一つです。
果たして、そうでしょうか。理解するのが難しいという点は、主観的なものだと思う(少なくとも私は難しいと思わない)ので、int Factorial( int number ) { if ( number == 1 ) { return 1; } else { return number * Factorial( number - 1 ); } }この再帰を使ったルーチンは、実行が低速で実行時に消費されるメモリを予測できないだけでなく、リスト17-9に示す繰り返し構造を使ったルーチンよりも理解するのが難しい。Code Complete 第二版上,p486-487より引用
実行が低速で実行時に消費されるメモリを予測できないという点を考えてみて、Cの二つの処理系で調べてみました。
.file "factorial.c"
.text
.p2align 4,,15
.globl factorial
.def factorial; .scl 2; .type 32; .endef
.seh_proc factorial
factorial:
.seh_endprologue
movl $1, %eax
cmpl $1, %ecx
je .L4
.p2align 4,,10
.L3:
imull %ecx, %eax
subl $1, %ecx
cmpl $1, %ecx
jne .L3
rep
ret
.L4:
.p2align 4,,2
rep
ret
.seh_endproc
.text
.align 4
.globl _factorial
_factorial:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
movl %ebx,-4(%ebp)
L11:
movl 8(%ebp),%ebx
L13:
cmpl $1,%ebx
jne L14
movl $1,%ebx
jmp L12
L14:
leal -1(%ebx),%edx
pushl %edx
call _factorial
addl $4, %esp
imull %eax,%ebx
L12:
movl %ebx,%eax
movl -4(%ebp),%ebx
leave
ret