2010

todo

  • Perl
    • AnyEvent
    • Catalyst
    • PSGI/Plack
  • Java
  • Perl6
  • HTML5
    • Web Sockets
  • Javascript
    • Node.js
  • KVS

keywords

  • Sync
  • Realtime
  • API
  • Offline web app
  • Cross platform

output

  • これらを使ったウェブサービスを最低2つ

hash を value で sort する

メモ。

$hash = { "ほげ" => 10, "ふが" => 5, "ぴき" => 30 };

for my $key (sort { $hash->{$b} <=> $hash->{$a} } keys %$hash) {
    print $key, ",", $hash->{$key}, "\n";
}

http://codepad.org/dRkHNzJM


Unicode正規化 と Unicode::Normalize

DBに日本語文字列を INSERT して検索できるようにする時に、全角・半角での表記のぶれが問題になる。そこで使われるのが Unicode::Normalize モジュール。

  • NFKC 関数で正規化し、それを検索用カラムに突っ込む
  • 検索ワードを NFKC 関数に通して、検索用カラムを検索する

ついでにテーブル作成時に COLLATE utf8_unicode_ci を指定しておけば、

ひらがな <> カタカナ、全角 <> 半角 を同じ文字として認識してくれます

http://www.tatamilab.jp/rnd/archives/000389.html#o

サンプル

use strict;
use warnings;
use utf8;
use Unicode::Normalize qw/NFKC NFKD NFC NFD/;
binmode STDOUT, ":utf8";

print "$Unicode::Normalize::VERSION\n";

my $src = "あアア がガガ ぱパパ むムム゙ abcabc 123123 ①②Ⅲ鄽";

print NFKC($src) . "\n";
repr(NFKC($src)); print "\n";
print NFKD($src) . "\n";
repr(NFKD($src)); print "\n";
print NFC($src) . "\n";
repr(NFC($src)); print "\n";
print NFD($src) . "\n";
repr(NFD($src)); print "\n";

sub repr {
  my $str = shift;
  for (0..length($str)-1) {
    printf("\\u%04X", unpack("U", substr($str, $_, 1)) );
  }
}
0.17
あアア がガガ ぱパパ むムム&#12441; abcabc 123123 12IIIiv
\u3042\u30A2\u30A2\u0020\u304C\u30AC\u30AC\u0020\u3071\u30D1\u30D1\u0020\u3080\u30E0\u30E0\u3099\u0020\u0061\u0062\u0063\u0061\u0062\u0063\u0020\u0031\u0032\u0033\u0031\u0032\u0033\u0020\u0031\u0032\u0049\u0049\u0049\u0069\u0076
あアア か&#12441;カ&#12441;カ&#12441; は&#12442;ハ&#12442;ハ&#12442; むムム&#12441; abcabc 123123 12IIIiv
\u3042\u30A2\u30A2\u0020\u304B\u3099\u30AB\u3099\u30AB\u3099\u0020\u306F\u309A\u30CF\u309A\u30CF\u309A\u0020\u3080\u30E0\u30E0\u3099\u0020\u0061\u0062\u0063\u0061\u0062\u0063\u0020\u0031\u0032\u0033\u0031\u0032\u0033\u0020\u0031\u0032\u0049\u0049\u0049\u0069\u0076
あアア がガガ ぱパパ むムム゙ abcabc 123123 ①②Ⅲ鄽
\u3042\u30A2\uFF71\u3000\u304C\u30AC\uFF76\uFF9E\u3000\u3071\u30D1\uFF8A\uFF9F\u3000\u3080\u30E0\uFF91\uFF9E\u3000\u0061\u0062\u0063\uFF41\uFF42\uFF43\u3000\u0031\u0032\u0033\uFF11\uFF12\uFF13\u3000\u2460\u2461\u2162\u2173
あアア か&#12441;カ&#12441;ガ は&#12442;ハ&#12442;パ むムム゙ abcabc 123123 ①②Ⅲ鄽
\u3042\u30A2\uFF71\u3000\u304B\u3099\u30AB\u3099\uFF76\uFF9E\u3000\u306F\u309A\u30CF\u309A\uFF8A\uFF9F\u3000\u3080\u30E0\uFF91\uFF9E\u3000\u0061\u0062\u0063\uFF41\uFF42\uFF43\u3000\u0031\u0032\u0033\uFF11\uFF12\uFF13\u3000\u2460\u2461\u2162\u2173

http://codepad.org/iJE0QGoG

参考

http://homepage1.nifty.com/nomenclator/unicode/normalization.htm


Queueの管理で並列ダウンロード

3スレッドでダウンロードを並列して行いたい。スレッドの queue を使って解決できた

use strict;
use warnings;
use threads;
use threads::shared;
use Thread::Queue;
use LWP::UserAgent;

# ダウンロード queue を生成する
my @download_list = (
    "http://example.com/example1.hoge",
    "http://example.com/example2.hoge",
    "http://example.com/example3.hoge",
    "http://example.com/example4.hoge",
    "http://example.com/example5.hoge",
    "http://example.com/example6.hoge",
    "http://example.com/example7.hoge",
    "http://example.com/example8.hoge",
    "http://example.com/example9.hoge",
);

# $queue をスレッド間で共有できるようにする
my $queue:shared = Thread::Queue->new();

# @download_list を enqueue する
$queue->enqueue(@download_list);

# スレッドを 3 つ作る
for (1..3) {
    # このループの中でほぼ同時に3スレッドが生成される
    threads->create(
        sub {
            my $ua = LWP::UserAgent->new();
            
            # queue がなくなるまで dequeue し続ける
            # ここで重要な点は、 $queue がスレッド間で共有されていて、
            # 各スレッドがダウンロード終了し次第、共有されている queue から dequeue してくる
            while(my $url = $queue->dequeue_nb()) {
                $url =~ m{ /(\w+.hoge) }xms;
                print "Downloading:$url\n";
                $ua->get($url, ":content_file" => "./dl/$1");
                print "Complete:$url\n";
            }
        }
    );
}

# 動いているスレッドを join して、全てのスレッドが終了するまで待つ
for (threads->list()) {
    $_->join();
}

ついったーはじめました

http://twitter.com/punytan


use threads; するときに注意すべきことの続編

なぜスレッド処理をするとインタプリタが落ちるのか原因がわかった。

Thread safety

use encoding ... is not thread-safe (i.e., do not use in threaded applications).

http://search.cpan.org/~dankogai/Encode-2.37/encoding.pm

Linux上のPerlで実行するとセグメンテーション違反になる。どうやら既知の問題だったらしい。


XML::RSSを使う時の注意点

<nicolive:community_name>hogehoge</nicolive:community_name>

RSS の item の中にこのような名前空間がある場合は、xmlns を指定してから記述しないとデータを読めない。

$rss->add_module(prefix=>'nicolive', uri=>'http://live.nicovideo.jp/');

add_moduleしておけばこのように読めるようになる。

$rssData{coName} = $item->{nicolive}->{community_name};

use threads; するときに注意すべきこと

use threads; で1日嵌った。環境は Active Perl - v5.10.1 built for MSWin32-x86-multi-thread

threadsを使う時、標準出力のエンコードをbinmodeで指定しておくとインタプリタが落ちる。なので、

my $cp932 = find_encoding('cp932');
print $cp932->encode("終了しました");

ように文字コードを指定しておく。次のように書くとクラッシュする

binmode STDOUT, ":encoding(cp932)";

参考

http://blog.livedoor.jp/dankogai/archives/51031595.html


« 12