あたらしものずきっ!

試してみたものとか、遊んでみたものを色々記してみます。

さくらスタンダードプラン上にTengをいれるほうほう

Amon2ついでにTengいれようとしたら、sqlがどうもsyntax error起こしているようで入らない。sqlite3がそもそもさくらに入っていなかったので、それが原因かと思っていれてはみた。

wget http://www.sqlite.org/sqlite-amalgamation-3.7.2.tar.gz
tar xvfz sqlite-amalgamation-3.7.2.tar.gz
cd sqlite-amalgamation-3.7.2
./configure --prefix=$HOME/local
make
make install

が、それでも無理だった。念押しで初期状態で入ってるDBD::SQLiteをcpanmで入れてみたけどそれでもダメ。SQL::Makerのバージョンも最新で特に問題はなさげ。こうなるとローカルではすんなり入ったTengをいじらねばなるまいかと、仕方なく、

cpanm --look Teng

で、あっさりと問題は解決。

  • lib/Teng.pm
sub _insert {
     my ($self, $table_name, $args, $prefix) = @_;

-   $prefix ||= 'INSERT';
+   $prefix ||= 'INSERT INTO';
     my $table = $self->schema->get_table($table_name);
  • lib/Teng/Plugin/Replace.pm
sub replace {
      my ($self, $table_name, $args) = @_;

      my $table = $self->schema->get_table($table_name);

      for my $col (keys %{$args}) {
           $args->{$col} = $table->call_deflate($col, $args->{$col});
      }
-     my ($sql, @binds) = $self->sql_builder->insert( $table_name, $args, { prefix => 'REPLACE' } );
+     my ($sql, @binds) = $self->sql_builder->insert( $table_name, $args, { prefix => 'REPLACE INTO' } );
      $self->_execute($sql, \@binds, $table_name);$

insertのほうはprefix渡さなければ大丈夫なんだけど、replaceはそうもいかない。にしてもなぜコケるのかがわからない。やはりsqliteのバージョン問題なのかな。

Amon2をさくらスタンダードプラン上に設置する

ちょろちょろと作業しつつ、なかなか動かないので面倒で放置してたけど、気合いれて動かしてみた。予めローカルで作成しておき、ひと通りできたところで転送という形。

ローカル編

cpanm --mirror http://orepan.64p.org/ Amon2

amon2-setup.pl Hello

さくらスタンダードプラン故の宿命で、とりあえずextlibを掘って、そこに依存モジュール突っ込む。installdeps使ってみたけど、うまく入らなかったので只管errorlogとにらめっこ。

plackup -r app.psgi

mkdir extlib
cpanm --force -l ./extlib/ Foo::Bar

ひと通りファイルが入ったところで、app.cgi作成。もちろんこれも一筋縄ではうごかないので、とりあえず動くまで入れる。

#!/usr/bin/perl
use lib qw(./extlib/lib/perl5);
use strict;
use warnings;
use utf8;
use Plack::Loader;

use Plack::Util;
 
use Path::Class qw(dir);

my $psgi_path = dir("home", "bar");
my $app = Plack::Util::load_psgi('/'.$psgi_path.'/app.psgi');
Plack::Loader->load('CGI',  port => 5000 )->run($app);

URLにこだわりたかったので、htaccessも追加。

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/app.cgi
RewriteRule ^app.cgi - [L]
RewriteRule ^(.*)$ app.cgi/$1 [QSA]

そしてHelloディレクトリ丸ごとさくらにあげる。

さくら編

とりあえず、ローカルでやったように、動くまで確認する。

cd ~/www/Hello/
cpanm --force -l ./extlib/ Foo::Bar

さくらスタンダードプランは、当日のエラーログをみるためには管理画面へアクセスしなければならないという面倒仕様なので、ブラウザとにらめっこしながらコンソール叩く。

Xcode4に上げた状態でppcサポートが入ってるCPANモジュールを入れる方法

訂正

ログ見直したところ、YAML::Syckは該当してませんでした。早とちりしてたようです。あと、環境設定とバージョンによっては記述が含まれてないようで(設定弄って入れなおしてみたら含まれてなかった)、実際にこけたら対処するのがいいのかも。



YAML::SyckでMakefile

-arch ppc

が入っているモジュールの場合、Xcode3からXcode4に上げた時点でppcサポートがなくなるため、testの段階でこけるようになる。

Makefileに修正いれればこけなくなるけど、毎回ppcサポート入ってるモジュールにそれをするのも面倒な場合は、Xcode3を別ディレクトリに入れる。その際にSDK関係のファイルは入れなくても問題ない。

MacBookAirを使ってAriakeWalkerの設定を行う方法

Windowsでのやりかたはあちこちに溢れてるんだけど、わりとmacでのやり方が見つからなかったので、今後の備忘録も兼ねてメモしておく。転送先デバイスGalaxy Tab SC-01C。

作業自体はTerminalにて。予めhomebrewを入れておく。

コミケカタログCD内のデータを編集するのに必要なコマンドを入れる。

brew install nkf
brew install sqlite
  • CCATALOG79.DB
  • C079CUTH.CCZ
  • C079CUTH.CCZ

を適当な場所に置いて、

sqlite3 CCATALOG78.DB .dump | nkf -Es -Sw -Lu | sqlite3 CCATALOG78_3_u.DB
mv C079CUTH.CCZ C079CUTH.zip
mv C079CUTL.CCZ C079CUTL.zip
mkdir H L
unzip C079CUTH.zip -d H
unzip C079CUTL.zip -d L

あとはSDカード直下に、AriakeWalker\C78\とディレクトリを作って、その中に

  • CCATALOG78_3_u.DB
  • H
  • L

を投下。ファイルに転送にはsmbよりもBluetoothを使うほうが、手間掛からないかもしれない。

参考memorandum

Yacafiの動作を読み解く3

http://d.hatena.ne.jp/hao_yayoi/20100827/1282843571:titlle=Yacafiの動作を読み解く2より引き続き

86 〜 95行目

 86     $yacafi =~ s/### NO PACK\n.+?### NO PACK END\n//sg;
 87     $yacafi =~ s/\n__END__\n.+$//s;
 88     $yacafi =~ s/'\.\$CURRENT_CLASS\.'/$CURRENT_CLASS/g;
 89     $yacafi =~ s/\$CURRENT_CLASS/$CURRENT_CLASS/g;
 90 
 91     my $global = '';
 92     for my $code ( $yacafi =~ /### GLOBAL\n(.+?)### GLOBAL END\n/sg ) {
 93         $global .= $code;
 94     }
 95     $yacafi =~ s/### GLOBAL\n(.+?)### GLOBAL END\n//sg;

引き続きYacafi.pmのソースコードを置換する処理。Yacafi.pmの中身の殆どがメタプログラミングのためのものというのがよくわかる。

97 〜 104 行目

 97     my $cgi = _read_file( ( caller(1) )[1] );
 98     $cgi =~ s/use (?:Yacafi|strict|warnings).*?;\n//sg;
 99     $cgi =~ s/\$Yacafi::/\$/g;
100 
101     my $shebang;
102     if ( $cgi =~ s/(\#\![^\n]+)//s ) {
103         $shebang = $1;
104     }

今度は、use Yacafiで実際に書いていたソースコードを対象にした置換作業。98行目でuseしてた行を消し、99行目でYacafiグローバル変数名から名前空間部分を消す。102行目にてシェバン(UNIXスクリプトの#!から始まる1行目)があればそれを変数に保持。

次はtemplate_builderなんだけど、多分これが一番手が込んでる感じなので、とりあえずここまで。

Yacafiの動作を読み解く 2

Yacafiの動作を読みとく より引き続く。

79 〜 95行目

_pack

 79     my $yacafi = _read_file( $INC{'Yacafi.pm'} );

_read_fileについては、143〜147に実装が書かれてる。

143 sub _read_file {
144     my $file = shift;
145     open my $fh, '<', $file or die $file . ': ' . $!;
146     do { local $/; <$fh> };
147 }

%INCには、読み込まれたファイル名とフルパスがkeyとvalueの組み合わせでつっこまれてる。Yacafi.pmのファイルパスを持ってきて、Yacafi.pmの中身を丸ごと取得する。$/はslurping(丸呑み)なモードのこと。79行目の$yacafiには、Yacafi.pm内のソースコードが丸々収まっていることになる。

次に、Yacafiソースコードから EXTEND 〜 EXTEND .. END の部分を対象にして正規表現のmatchを行う。

 81     # extends
 82     $yacafi =~ s!### EXTEND (\w+)\n(.+?)### EXTEND \1 END\n!
 83         $args{extends}->{$1} ? $2 : ''
 84     !esg;

実態は、

$yacafi =~ s!!!esg;

84行目のesgは、

  • e:式の右側の評価を行なう
  • s:ワイルドカードのドット( . )が改行にもマッチするようにする
  • g:繰り返し置換

特にYacafi.pmを弄っていない場合、importで呼び出された時に渡されるハッシュのextendsがtemplateをkeyの一つとして保有していれば、2番目にマッチした値が 382 〜 607行目の ###EXTEND 〜 ### EXTEND template END と置き換わる。

一見して分かりにくいこと間違いないけれど、

$yacafi =~ /### EXTEND (\w+)\n(.+?)### EXTEND \1 END\n/;
$yacafi = $args{extends}->{$1} ? $2 : '';

と同義。

とりあえずここまで。82〜84行目の把握にかなり時間食った気がする。

Yacafiの動作を読み解く

軽量フレームワークの話題が殆ど上がらなくなった感もあり、とってつけたような記事に思われない丁度いいタイミングかなーとか思ったのでやってみることにした。

wget http://svn.coderepos.org/share/lang/perl/Yacafi/trunk/lib/Yacafi.pm

以前Yacafiを使った掲示板を書いてた事があったけど、当時は細かい挙動とか全然分かってなかったから、方々からのコピペで更に理解不可能になり気味だった。理解を正確に行って、使えるような代物にするのが目的。

2 〜 36行目

YacafiのTemplateに関する各種環境設定。

 our $TEMPLATE_PARAMS = +{

の +{ については、perlrefを見ると分かる。

42 〜 75行目

  • import
45    my $caller = caller;
46    $CURRENT_CLASS = $args{current_class} || $caller;

引数にcurrent_classをkeyとした値を渡すと、それが基本classとして扱われる。そうでなければmainが基本classになる。

実際に書くとすると、

use Yacafi current_class => 'hogehoge';

という具合。

  • pre config
 49     if (   exists $args{extends}
 50         && exists $args{extends}->{template}
 51         && ref( $args{extends}->{template}->{params} ) eq 'HASH' )
 52     {
 53         while ( my ( $key, $val )
 54             = each %{ $args{extends}->{template}->{params} } )
 55         {
 56             $TEMPLATE_PARAMS->{$key} = $val;
 57         }
 58     }

指定のハッシュが渡されていれば、templateのパラメータを指定。
実際に書くと、

use Yacafi current_class => 'hogehoge', extends => {
    template => {
        params => {
            tag_start => '<tmt',
            tag_end   => 'tmt>',
        },
    },
};

こんな具合。params内の指定は24〜35行目のkey。

60 〜 61行目

pack

 60     # create a pack file$
 61     _pack(%args) if @ARGV && $ARGV[0] eq '--pack';$
perl hogehoge.cgi --pack > hogehoge.cgi

な感じで、Yacafi.pm + index.cgiなファイルを作るコマンドのための行。_pack自体は77〜141行に。

63 〜 72行目

function export

 63     # functions export
 64     no strict 'refs';
 65     for my $name (qw/ dispatch query controller model view redirect filter /    )
 66     {
 67         *{ $caller . '::' . $name } = \&{$name};
 68     }
 69     if ( exists $args{extends} && exists $args{extends}->{template} ) {
 70         *{ $caller . '::view_template' } = \&view_template_nocompile;
 71     }
 72 

呼び出し元のスクリプトへ、メソッドを定義する。

  • dispatch
  • query
  • controller
  • model
  • view
  • redirect
  • filter

が使えるという具合に。
なお、

use Yacafi extends => { template => { params => .... } };

のようにtemplateを定義しておくと、view_templateメソッドで 407 〜 414行目のview_template_no_compileが呼び出されるようになる。

次は_pack辺りでも触る。