Hatena::Groupcside

Cside::StudyMemo このページをアンテナに追加 RSSフィード

メインブログに書くまでもない自分用メモを垂れ流す。日々是勉強也。

カテゴリー

2014-01-05

[]Perlを書くときにいつも迷うこと

  • 複数のものを返すメソッドで、return value をリストにするか ArrayRef にするか
  • getter / setter のメソッド名に get_ / set_ を付けるか否か
    • (これはPerlにかがったことじゃないけど)

[]$`, $&, $'

いつも忘れる。

$`マッチした文字列に先行する部分
$&マッチした文字列全体
$'マッチした文字列に後続する部分

Perl 5.10 から、等価な変数である ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} も使えますが、これらが定義されるには、正規表現に /p (保存(preserve)) 修飾子をつける必要があります。

perlreref - Perl の正規表現のリファレンス - perldoc.jp

2013-12-02

[]Test::BaseにはOOインターフェイスがある

    use Test::Base;
    my $blocks1 = Test::Base->new;
    my $blocks2 = Test::Base->new;

    $blocks1->delimiters(qw(!!! @@@))->spec_file('test1.txt');
    $blocks2->delimiters(qw(### $$$))->spec_string($test_data);

    plan tests => $blocks1->blocks + $blocks2->blocks;

    # ... etc

http://search.cpan.org/~ingy/Test-Base-0.60/lib/Test/Base.pm

2013-11-03

[]コマンドライン引数処理モジュール選定委員会

なんで GetOpt::Long じゃダメか

  • バッドノウハウがいくつかあって、いちいち調べるのがかったるい。
  • これが一番でかいけれど、バリデーションルールとドキュメントをそれぞれ書かなければならないのがだるい。
    • バリデーションルールから自動でUsage作れや!

要件

  • G::L みたいにバッドノウハウ多くないやーつ
  • バリデーションにこけたら勝手によしななドキュメント自動生成して吐いて欲しい
  • GetOpts::Long しか触ったことない人でもパッと見読めること
  • 引数の方やrequired or not がコードから一瞬でわかること
  • あとできたらperl5.8とかで動いてほしいかな

候補

結論:なんか Getopt::Compact::WithCmd でいいやと思った。

__END__

  • Smart::Options
  • opts
    • DEPRECATED になってた
  • Getopt::Compact::WithCmd
  • Docopt

2013-10-25

[]引数のハッシュのキーの順番を保持したい場合

hashでなくarrayで受け取ればいい

func(
    foo => 'bar',
    baz => 'foobar',
);

sub func {
    my @args = @_; # not %args
    while (my ($key, $val) = splice @args, 0, 2) {
        ...
    }
}

2013-09-19

[]use FindBin qw($Bin); みたいに変数を Export する

use constants した定数は実体は関数だから変数展開とかできなくてだるいので、変数としてExportしたい。

package Foo;
use common::sense;
use Exporter qw(import);

our @EXPORT_OK = qw($Bar);

our $Bar = 'constant variable';

1;
use Foo qw($Bar);

warn $Bar; #=> 'constant variable'

なぜか $Bar はクラス変数にしないと動かない。

2013-06-20

[]Text::ASCIITableをマルチバイト文字に対応させる方法

cb_count というオプションを使えば良い。

use Text::ASCIITable;
use Text::VisualWidth::PP;
use utf8;

Text::ASCIITable->new(+{ cb_count => \&Text::VisualWidth::PP::width });

これでマルチバイト文字を含んだ時もよしなにやってくれる。

2013-06-17

[]Reply.pm の便利機能について

Reply is awesome! - tokuhirom's blog

LoadClassプラグインを使いましょう

~/.replyrc に以下の一行を書き足すと、

[LoadClass]

ロードしてないモジュールでもよしなに自動ロードしてくれる。

(下はLWP::UserAgentをuseせずにやってる。Can't locateエラーにならない)

http://cdn-ak.f.st-hatena.com/images/fotolife/C/Cside/20130617/20130617221938.png


Reply、Carp::REPLより軽いし、入りやすいし、コードも読みやすいしで好きだ。

あと不満なのはpackage名の補完がきかないことくらいなので、誰かやってください。(投げ)

2013-06-14

[]特定のsubtestだけを実行する方法

まずprove実行時にTest::Flattenをuseするようにするように、

.proverc

--exec "perl -Ilib -It/lib -MTest::Flatten"

すると、SUBTEST_FILTERという環境変数でフィルタ出来るようになる

SUBTEST_FILTER=foo prove -lvc t/

これで /foo/ にマッチするsubtestだけ実行される。

https://metacpan.org/module/XAICRON/Test-Flatten-0.09/lib/Test/Flatten.pm#SUBTEST_FILTER

2013-06-12

[]コントローラーのテストについて

  • JSオフでも遷移が可能なページ -> WAFにコントローラーのテスト機構があればそれを使う、なければ Plack::Test
  • JSがないと遷移が不可能なページ -> Selenium や PhantomJS
    • Jenkinsサーバー に PhantomJS が入ってないと CI に乗せられないのがアレか

2013-06-06

[]Data::Dumper のよく使うオプション

perlで改行など特殊文字が含まれるものをDumpする時は - $shibayu36->blog;

Useqq オプション便利すね。


Indent, Terse

よく使う。出力結果をコンパクトにしてくれる。

use Data::Dumper;

my $data = { foo => 1, bar => [1, 2] };
warn Dumper $data;
# $VAR1 = {
#           'bar' => [
#                      1,
#                      2
#                    ],
#           'foo' => 1
#         };

local $Data::Dumper::Indent = 1;  # インデントの深さレベル
local $Data::Dumper::Terse  = 1;  # "$VAR1 = " 消す

warn Dumper $data;
# {
#   'bar' => [
#     1,
#     2
#   ],
#   'foo' => 1
# }

ちなみにオプションは、localを使って設定しとくとスコープ限定できて良い。

自分は、Vimのスニペットに

use Data::Dumper;
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Terse  = 1;
warn Dumper 

を d とかで呼び出せるように登録してる。

Deparse

サブルーチンをDumpできる。ただし実体とまったく同じものではない。

use Data::Dumper;
use Path::Class qw(file);

warn Dumper \&file;
# $VAR1 = sub { "DUMMY" };

local $Data::Dumper::Deparse = 1;
warn Dumper \&file;
# $VAR1 = sub {
#             package Path::Class;
#             use strict 'refs';
#             'Path::Class::File'->new(@_);
#         };

Data::Dump::Streamer 使っても同じ事ができる。


こっからは Data::Dumper からは脱線した余談。 


Data::Dump について

デフォルトだとインデントが豪快な Data::Dumper に対して、Data::Dump は出力が最初からコンパクト。

my $data = { foo => 1, bar => [1, 2] };

use Data::Dump qw(dump);
warn dump $data;
# { bar => [1, 2], foo => 1 }

use Data::Dumper;
warn Dumper $data;
# $VAR1 = {
#           'bar' => [
#                      1,
#                      2
#                    ],
#           'foo' => 1
#         };

コンパクトなほうが好きな人はこれ使えばいいと思う。

僕はオブジェクトのdump結果が Data::Dumper よりも見難く感じるから使ってない。

おまけ:変数名も一緒にdumpする

Data::Dumper::Names というのがある

use Data::Dumper::Names;

my $foo;
my @bar = qw/this that/;
warn Dumper($foo, \@bar);
# $foo = undef;
# @bar = (
#     'this',
#     'that'
# );

おまけ2:カラフルなdumper

Data::Printer というのがある

See Also

2013-04-09

[]直前の0時のunixtime

バッチ処理でたまに使う。

my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime;
my $last_midnight = timelocal(  0,  0,  0, $mday, $mon, $year);

2013-03-09

[]$dbh->finish;

用意したSQL文を解放する。

2013-03-08

[]Mo[ou]seでBridgeする

handlesを使うと手軽にできる

package Foo;
use Mouse;

has bar => (
   is => 'rw',
   isa => 'Foo::Bar',
   handles => [qw(bar_method)],
);
# 以下と同じ
# sub bar_method { shift->bar->bar_method(@_) }

has baz => (
   is => 'rw',
   isa => 'Foo::Baz',
   handles => +{ baz_method => 'baz_real_method' },
);
# 以下と同じ
# sub baz_method { shift->bar->baz_real_method(@_) }

2013-02-05

[][]マッチする文字列で一番後ろのものだけを置換

foofoofoo を foofoobar と置換したい場合

$str =~ s/(.*)foo/$1bar/;

2013-01-11

[]MySQLのFROM_UNIXTIME(), UNIX_TIMESTAMP()をPerlで

use Time::Piece ();

# datetime -> unixtime
sub unix_timestamp {
    Time::Piece::localtime->strptime(shift, '%Y-%m-%d %H:%M:%S')->epoch;
}

# unixtime -> datetime
sub from_unixtime {
    Time::Piece::localtime(shift)->strftime('%Y-%m-%d %H:%M:%S');
}

say from_unixtime(time); #=> 2013-01-11 12:03:28
say unix_timestamp('2013-01-11 12:03:28'); #=> 1357873408

DateTime::Format::MySQLでも同じ事できた気がする

2013-01-06

[]perldocコマンドでファイル演算子をひく

perldoc -f -f

とかで普通に引ける。built-in functionにカテゴライズされてるのか…。


ちなみに $@ みたいな変数の意味は perldoc -v '$@' とかで引ける。

2012-12-29

[]ハッシュの参照/更新をトレースする

これはtieで実現できるんだけど、

個人的にはこのためにパッケージ作るのが面倒くさい。

もっと簡単にハッシュの変更をトレースできるモジュールないかなぁと探してたら Sub::Trace というものがあった。

https://metacpan.org/module/Tie::Trace

極限までお手軽な感じだし、これでよさそう。

2012-12-26

[]return func() と my $ret = func(); return $ret で挙動が違う

https://github.com/Cside/Brownie/commit/82d4708db6d20ed4f5aaa0331a1e8a30536c4941


wantarrayみてるわけでもないのに。マジで何が起こってるんだろう…。

2012-12-23

[]データ構造のDiffをみる


https://metacpan.org/module/Data::Difflet

[]Code Referenceから、関数名とか定義場所を得るの法

拙作のSub::Inspectorでできます。

use Sub::Inspector;

my $code = File::Spec->can('canonpath');

my $inspector = Sub::Inspector->new($code);

print $inspector->file; #=> '/Users/Cside/perl5/ ... /File/Spec/Unix.pm'
print $inspector->line; #=> 71
print $inspector->name; #=> 'canonpath'

2012-12-16

[]Catalystのコンソールに出力される情報が結構気が利いてた

metacpan.orgはGithubでソースが公開されてるので手元で動かしてみた。metacpanはCatalystで作られてるんだけど、Catalystがコンソール画面に吐く情報がなかなか気が利いてた。


/search?sort=miyagawa にアクセスした場合の画面

f:id:Cside:20121216145814p:image

リクエストごとに

  • クエリパラメータ情報
  • そのリクエストで経由したパス

を吐いてくれる。

開発中のデバッグにかなり役立ちそうだと思った。

これ、Plack Middlewareに切り出したいなあ。


Railsとかはどういう情報はいてるんだろ。