タグ

ブックマーク / gfx.hatenadiary.org (30)

  • Perl XS を書くようになったきっかけ - Islands in the byte stream (legacy)

    THE INTERVIEWS がサービス終了ということで、一つだけ消えるには惜しいというか懐かしい記事があったので少し加筆修正して転載します。JHackers でも似たようなことを話してますね。 Perl XS を書くようになったきっかけ、また、どのようにして今のような XS マジシャンになったのか。そのあたりの事をお聞かせください 2000年頃の話です。ぼくはCGIスクリプトでちょっとしたゲームデータの集計サイトをやりたくてプログラミングを覚えたのでした。これがそこそこ重い処理で、次第にもっと高速にしたいと考えるようになりました。一方、当時ぼくはお金もなくVPSも一般的でなかったので、CGIスクリプトしか選択肢はありません。そこで初心者ながらいろいろ調べることにしました。 とりかかったのは行指向のテキストで保存していたデータをSQLiteにすることでした。しかし当時はWindows上で開

    Perl XS を書くようになったきっかけ - Islands in the byte stream (legacy)
    n2s
    n2s 2013/12/04
  • chomp() は $/ に依存していると知れ! - Islands in the byte stream

    perldocにあるように、chomp()の挙動は $/ に依存します。ということは、うっかり local $/ したスコープで chomp() を行うと、何もおきません。 この結果起きる現象がきわめて不可解なので、readlineの直後以外の場面ではchomp()を使わず s/\r?\n\z//xms するのが無難でしょう*1。 use strict; use warnings; local $/; my $s = "Hello\n"; chomp $s; print "[$s]\n"; # => #[Hello #] Xslateがまさにこれにはまっていたので修正しました。 https://github.com/xslate/p5-Text-Xslate/commit/92c7387b0f0ebdad5761c420a54564b9e8d2f635 [追記] *1:はてブのコメントをう

    chomp() は $/ に依存していると知れ! - Islands in the byte stream
    n2s
    n2s 2013/11/16
    「うっかり local $/ したスコープで chomp() を行うと、何もおきません」「readlineの直後以外の場面ではchomp()を使わず s/\n\z//xms するのが無難でしょう」
  • visual_widthというgemを書いた - Islands in the byte stream (legacy)

    UnicodeのEast Asian Width (東アジアの文字幅)特性を扱うgemを書いた。CPANの Unicode::EastAsianWidth, Text::VisualWIdth::PP, Text::UnicodeTable::Simpleの機能をマージしたようなものになってる。文字特性のデータはUnicode仕様書から自動生成している。 https://rubygems.org/gems/visual_width ターミナルにさくっとテーブルを書きたいときは日語でもくずれないので便利かも。 # VisualWidth::Table require 'visual_width/table' t = VisualWidth::Table.new( style: [ { align: :center, width: 10 }, { align: :center, width:

    visual_widthというgemを書いた - Islands in the byte stream (legacy)
  • PerlでWebAppの開発に必要なN個のこと - Islands in the byte stream (legacy)

    あるプログラミング言語で実際にWebAppを開発できるようになるまで、何が必要だろうか。言語仕様の習得は終えているとしよう。おそらく、最低限以下のような知識が必要だと思われる。とりあえずPerlについて知っていることを書いた。 パッケージマネージャ まずライブラリの管理。モジュールをインストールし、可能であればバージョンを固定し、適切にロードする機能が必要だ。Perlの場合は cpanm というCPANクライアントでライブラリをインストールする。バージョンの固定とライブラリパスの設定は carton で行う。 https://github.com/miyagawa/cpanminus https://github.com/miyagawa/carton アプリケーションサーバ Webサーバへのインターフェイスとしては、PSGIという仕様がある。PSGIに準拠したツールキットとしてPlack

    PerlでWebAppの開発に必要なN個のこと - Islands in the byte stream (legacy)
  • Released rack-devfavicon - Islands in the byte stream (legacy)

    開発環境と番環境で favicon を変える というのに感動したのでRack middlewareでやってみました。というか、昨日のPlack::Middleware::DevFaviconをRackに移植しただけですけど。 Plack版とおなじく単に favicon.ico ないし favicon.png という名前にマッチしたらグレースケールにして返すというだけの代物ですが、Rack middlwareなので簡単に導入できるのが楽かなと。 使い方は以下のとおり。faviconを配信するミドルウェアよりも先にuseしてください。 if ENV['RACK_ENV'] != 'production' require 'rack-devfavicon' use Rack::DevFavicon end map "/favicon.ico" do run Rack::File.new("#{

    Released rack-devfavicon - Islands in the byte stream (legacy)
    n2s
    n2s 2013/09/09
    id:entry:159636010での「Rack middleware層でやりたい」は誤記だと思っていました。ごめんなさい。
  • Released Plack::Middleware::DevFavicon - Islands in the byte stream (legacy)

    開発環境と番環境で favicon を変える というのに感動したのでPlack middlewareでやってみました。 単に favicon.ico ないし favicon.png という名前にマッチしたらグレースケールにして返すというだけの代物ですが、enable_ifで簡単に導入できるのが楽かなと。 使い方は以下のとおり。P::M::Staticの前にenableしてください。 builder { enable_if { $ENV{PLACK_ENV} eq 'development' } 'DevFavicon'; enable 'Static', path => qr{/favicon\.(?:ico|png)$}, root => $path_to_assets; ...; }; https://github.com/gfx/Plack-Middleware-DevFavico

    Released Plack::Middleware::DevFavicon - Islands in the byte stream (legacy)
    n2s
    n2s 2013/09/08
    開発環境ではグレースケールなfaviconを表示。ほほー / インスパイア元:http://qiita.com/hotchpotch/items/70d1446fec081fc95eee
  • [Ruby] オーバーライドとか無視してKernel#classを直接呼びたい - Islands in the byte stream (legacy)

    直接 `self.class` を呼ぶと、#class がオーバーライドされている可能性があるので任意のオブジェクトに対して呼ぶことはできません。よってKernel#classを直接呼ぶ必要があります。そこで、以下のように#classのUnboudMethodを得て、それにレシーバを与えて呼び出すことで解決できます。 def self.class raise "boom!" end get_class = Kernel.instance_method(:class) # and later p get_class.bind(self).call とはいえパフォーマンスがあまりよくないのでもっといい方法があればそっちを使いたい。 あと Kernel#class の上書きはやめてくださいお願いしますm(_ _)m。 [追記] 別解もあるようです。 このままだと汎用的には使えないのでFixnum

    [Ruby] オーバーライドとか無視してKernel#classを直接呼びたい - Islands in the byte stream (legacy)
    n2s
    n2s 2013/09/06
  • bless($args, $class) is a bad practice - Islands in the byte stream (legacy)

    さいきん散見される以下のようなコードは悪いコードです。 # usage: Foo->new({ age => 42 }) sub new { my($class, $args) = @_; return bless $args, $class; } それは、ハッシュリファレンスと想定される$argsのそのままつかっているため、引数としてハッシュリテラル以外の何かを渡すと予期しない動作を引き起こすという点です。 たとえば、以下のような使い方は問題を引き起こします。 my %args = (age => 20); my $o1 = Foo->new(\%args); my $o2 = Foo->new(\%args); # ここで $o1 と $o2 は同じオブジェクトになってしまう このような場合、$argsはコピーすべきです*1。またついでにハッシュリファレンスではなくkey-value

    bless($args, $class) is a bad practice - Islands in the byte stream (legacy)
    n2s
    n2s 2013/08/18
  • JSX minifierの圧縮性能 - Islands in the byte stream (legacy)

    JSX compilerのソースコードで検証してみました*1。 Mode Size(KiB) Ratio original 1507 1.00 JSX minifier 277 0.18 Closure Compiler/D 602 0.40 Closure Compiler/A 301 0.20 対象にしたソースコードがJSXから変換したJSというやや特殊な状況ですが、Closure CompilerのADVANCED_OPTIMIZATIONSよりもサイズが小さくなりました。また、ADVANCED_OPTIMIZATIONSと異なりJSX minifier*2はコードを破壊する圧縮は一切行わないので、圧縮したらコードが動かなくなるということが非常に起こりにくくなっています。しかしそれでも、JSXの豊富な型情報を使って圧縮すればADVANCED_OPTIMIZATIONSよりもサイズを小

    JSX minifierの圧縮性能 - Islands in the byte stream (legacy)
  • perl v5.18.0 released! - Islands in the byte stream (legacy)

    perl v5.18.0 がリリースされました。 https://metacpan.org/release/RJBS/perl-5.18.0 このリリースでの新規機能はほとんどないものの、二つの非常に大きな変更があります。 ハッシュキーのランダム化 each(), keys(), values() で返されるハッシュキーの順番がハッシュ毎にランダムになりました。同じプロセス内、同じキーセットのハッシュでさえ順番が一致しなくなります。 use 5.18.0; use strict; use warnings; my %a = map { $_ => 1 } qw(foo bar baz); my %b = %a; say join ", ", keys %a; say join ", ", keys %b; 実行例: $ perl randomized-keys.pl baz, bar, f

    perl v5.18.0 released! - Islands in the byte stream (legacy)
    n2s
    n2s 2013/05/19
    きたか / ハッシュキーのランダム化…うわあ…Rubyみたいに登録された順にkeyが並ぶようにはできないものだろうか
  • Rubyのレキシカル変数むずかしい - Islands in the byte stream (legacy)

    同じシンボルの参照でも、代入(宣言)前後で参照しているものがまったく違うものになるのがPerlと違って難しい。 class Base def initialize self.foo = "init" end def foo=(value) @foo = "<#{value}>" end def foo @foo end end class Derived < Base def f # selfがないとメソッド呼び出しと変数参照は同じに見える puts "In f()" p foo # Base#foo() p foo = 2 # レキシカル変数の宣言 p foo # fooはレキシカル変数 end def g # self付きだと常にメソッド puts "In g()" p self.foo p self.foo = 2 p self.foo end end d = Derived.new

    Rubyのレキシカル変数むずかしい - Islands in the byte stream (legacy)
    n2s
    n2s 2013/04/30
    myやvarで明示的に宣言する構文がないですからねぇ…
  • Perlの m// は中身が固定文字列だと爆速になる - Islands in the byte stream (legacy)

    [追記] 実際に検証してみると、パターンが短いと index() のほう速いこともあるようです。パターンが長いと正規表現のほうが高速になるのでそもそもアルゴリズムが違うようですね。 よってこのエントリの内容は必ずしも正確ではありません! cf. https://gist.github.com/kazuho/5410635 [/追記] Perlの話題を日語で – Lingr で出た話題です。 Perlの正規表現マッチはパターンが単純だと index() とおなじく Boyer-Moorアルゴリズムで検索するので非常に高速です。要は最適化のつもりでパターンマッチをindex()に書き換えるのは無意味なのです。 ソースは pp.c や regexec.c あたりを fbm_instr() で検索かな? ドキュメントもどこかで読んだ気がするのですが思い出せず>< perl -MDevel::Pe

    Perlの m// は中身が固定文字列だと爆速になる - Islands in the byte stream (legacy)
    n2s
    n2s 2013/04/18
    ラクダ本の初版にも書いてありましたな / おや、追記が
  • Data::Dumper が壊れているという惨事 - Islands in the byte stream (legacy)

    あるいは PERL_CPANM_OPT=-n は危険だという話。 それはこのtweetから始まった。 結局これは Data::Dumper 2.143 が壊れていたからなのだが、そこに至るまでがちょっと大変だったので記録しておく。 まず、再現スクリプトは以下のものだった。 # executed in perl 5.10.1 use strict; use warnings; use Data::Dumper; use Text::Xslate; my $tx = Text::Xslate->new({ syntax => 'TTerse' }); my $template = <<TMPL; [% value | dump %] TMPL my $value = +{ 'ab' => 'c', }; print Dumper($value); my $ret = $tx->render_s

    Data::Dumper が壊れているという惨事 - Islands in the byte stream (legacy)
    n2s
    n2s 2013/03/06
  • Xslateのキャッシュ更新メカニズムの変更 - Islands in the byte stream (legacy)

    1.5015までのXslateのキャッシュ更新メカニズムでは問題があると報告されたため、1.5016で修正しました。 cache => 1 のとき、従来は render() ごとにテンプレートのキャッシュファイルのmtimeとテンプレートファイルのmtimeを比較してキャッシュの更新が必要かどうかをチェックしていたのでした。しかし、これでは以下の様なシナリオの元でキャッシュ更新ミスが発生しうるのでした*1。 foo.tx のmtimeが11:00とする 12:00 に foo.tx を render() する。このときcacheの mtime は 12:00 となる foo.tx を更新し、foo.txのmtimeが 12:00 になる foo.tx を render() すると、cacheはtemplate fileより古くないため、cacheを使う 1.5016では、キャッシュのmti

    Xslateのキャッシュ更新メカニズムの変更 - Islands in the byte stream (legacy)
    n2s
    n2s 2012/08/05
    「キャッシュのmtimeをテンプレートファイルと同じに設定することで更新ミスをなくしました」なるほど、これは大事なテク
  • EastAsianWidth判別用コードを自動生成する - Islands in the byte stream (legacy)

    VisualWidth実装用に、Unicode::EastAsianWidth みたいなものを自動生成するためのスクリプトを書いた。unicode.orgからとってきたデータをもとに生成しているので安心。 これはJSX用だけど、他の適当な言語のためのコードを生成するのも難しくないはず。 #!/usr/bin/env perl use 5.14.0; use strict; use warnings; use LWP::Simple qw(get); use Text::Xslate; use Log::Minimal qw(infof); my $SPEC = "http://www.unicode.org/reports/tr11/"; my $DATA = "http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt"; my %p

    EastAsianWidth判別用コードを自動生成する - Islands in the byte stream (legacy)
  • JSにコンパイルされたDartがPerlより速い件 - Islands in the byte stream (legacy)

    Dartのインストールが簡単になっていたので試してみたところ、Perlよりも高速だった。 なにこれ悔しい。 Dart: void main() { final t = new Stopwatch(); t.start(); final a = new List<int>(); for(var i = 0; i < 1000000; ++i) { a.add(i); } for(var i = 0; i < a.length; ++i) { ++a[i]; } var sum = 0; for(var i = 0; i < a.length; ++i) { sum += a[i]; } print(sum); print(t.elapsedMilliseconds / 1000); } Perl: use 5.12.0; use Time::HiRes qw(gettimeofday tv_

    JSにコンパイルされたDartがPerlより速い件 - Islands in the byte stream (legacy)
  • JSでi++と++iどっちが速い? - Islands in the byte stream (legacy)

    結論から言うと、現在のChromeのみをターゲットにして最適化するという特殊なケースを除き*1、どちらでも変わらないといえます。 [追記] 指摘を受けて再考してみました。そもそもjsperfでは初期化コード(今回はdataなどの初期化に使用)は一度しか走らないにもかかわらず、このベンチマークコードではdataの中身を書き換えています。これがスコアに影響を与えていたようです。 data[index] = data[index] * 2をdata[index] = index * c にした結果はChromeでも安定して双方有意差なしという結果になりました。 http://jsperf.com/postfix-or-pretfix-increment/4 JSのベンチマークの難しさを思い知りました。 [/追記] http://jsperf.com/prefix-or-postfix-incre

    JSでi++と++iどっちが速い? - Islands in the byte stream (legacy)
  • 2012年はプログラミング言語を作りたい - Islands in the byte stream (legacy)

    当は2011年の1-3月の間にやろうと思っていたのだが、卒業の危機などがあり思うように進まなかった。しかし今年Perl/XS以外にもC++, Objective C++, Java, ActionScript, JavaScript, Rubyなどでコーディングする機会があり、自分が欲しい言語が具体的になってきた。 私が欲しいのは、Perlの次を担えるような言語だ。それは必ずしも私の言語でなくてもいいのだが、とにかく「next Perl」が欲しい。 Perl言語のいいところは何か。それは言語に密結合した正規表現構文とテキスト処理機能、シンボルテーブルなど内部データ構造*1や後付けのOOP*2のような原始的な機能の露出、標準ドキュメントフォーマット*3とビューア*4、RAIIとダイナミックスコープだ。私は、これらすべてを備えている言語をPerl以外に知らない。 一方で、不要な機能もある。特

    2012年はプログラミング言語を作りたい - Islands in the byte stream (legacy)
    n2s
    n2s 2011/12/31
    かっこいい…
  • lib::xi - installs missing libraries on demand - Islands in the byte stream (legacy)

    gistなどで公開されているPerlスクリプトを実行する際、モジュールが足りないことがよくあります。そういう場合はCan't locate Foo.pm ...というエラーメッセージを見ながらモジュールをインストールするわけですが、決まりきった作業にうんざりしたので自動的にそれをするモジュールを書きました*1。 https://github.com/gfx/p5-lib-xi `perl -Mlib::xi script.pl`とするだけで、足りないモジュールをcpanmで適当にインストールしてくれます。 -Mlib::xi=extlibとすれば既存の環境を壊すことなくlocal::lib的にextlib/にインストールして実行できますし、-Mlib::xi=-L,extlib,-qなどとしてcpanmにオプションを渡すこともできます。 これで退屈なインストール作業をしなくてすむはずです。

    lib::xi - installs missing libraries on demand - Islands in the byte stream (legacy)
  • Re: モダンPerl連載第43回 - Islands in the byte stream (legacy)

    モダンPerlの世界へようこそ#43がXslateの話だと思ったらノイズ呼ばわりされたでござる、の巻。 著者であるid:charsbarさんの捕捉によれば以下のとおり モダンPerl連載第43回 - Charsbar::Note 「TTの代用品としての」Template::AlloyとText::Xslateについて簡単にまとめてみました。 ということですが、Catalystをビジネスに使うチームこそがPerlのスタンダードであり「周辺」はスタンダードを重んじるべきという論調には違和感を覚えました。 独自プロジェクトではなく家の改善にリソースを貸すべきという批判はたしかにMouseについては当てはまるのかもしれませんが、XslateはTemplate-Toolkitを代表とする既存のプロジェクトとは全く関係ない文脈で開始したプロジェクトです。TTプロジェクトに関わるという選択肢は考えもし

    Re: モダンPerl連載第43回 - Islands in the byte stream (legacy)
    n2s
    n2s 2011/07/24