Tag: perl



2011 12月15日

MAMP

Apache+MySQLサーバをmacで動作させる事ができる。macにはもともとApacheもperlもインストールされているけど、バージョンが古いし、管理も面倒なのでMANPを使うメリットはおおいにあると思う。もともとはPHP+MySQLのローカル環境を構築するためのもの…かな?

参考:Mac OS Xのローカル環境(MAMP+MacPorts)で Movable Typeを動かしてみよう – 準備編  [ 09.06.24 update ] 【 gabs.log|おしゃべり好きなWEB制作者のたわごと 】

MAMPをインストール

MAMP

MAMPからダウンロードしてインストールする。

MacPortsのインストール

makeとか使うのでXCodeが必要。OSのバージョンにあったものをダウンロードする。

  • The MacPorts Project — Download & Installation
  • MacPortsの初期化&設定

    Terminalでコマンドを実行

    Selec All Code:
    echo 'export PATH=$PATH:/opt/local/bin:/opt/local/sbin/' >> ~/.bashrc
    echo 'export MANPATH=$MANPATH:/opt/local/man' >> ~/.bashrc
    echo 'source ~/.bashrc' >> ~/.bash_profile
    sudo port -d selfupdate
    sudo port -d sync

    perlのPATHを変更

    元のperlをperl.bakにリネームして、シンボリックリンクを貼る。これをしておかないと元々インストールしてあるperl(/usr/bin/perl)を参照してしまうため。

    Selec All Code:
    cd /usr/bin/
    sudo mv perl perl.bak
    sudo ln -s /opt/local/bin/perl /usr/bin/perl

    cpanmをインストール

    perlモジュールを簡単にインストールできるcpanmをインストールする。

  • ArtifactSauce: cpanmをMac OS Xにインストールする
  • sudoでインストールすると /opt/local/lib 以下にインストールされる。

    Selec All Code:
    sudo cpanm Mojolicious
    or
    cpanm -S Mojolicious

    ユーザー権限でインストールした場合は、ホームディレクトリ ~/perl5/lib/ 以下にインストールされるので、この場合はPATHの指定が必要。コード側に書くか、あらかじめ設定しておく必要がある。
    Apacheのconfigに設定するのが吉かな?

    httpd.confに記述

    Selec All Code:
    SetEnv PERL5LIB /Users/clicktx/perl5/lib/perl5
  • KMsWiki: Perl/@INC – Perlのライブラリの検索PATHを格納した配列のこと。 例えば、コマンド…
  • CGIでの環境変数PERL5LIBの設定 | OKWave
  • MAMPでCGI(perl)を実行できるようにする

    /Applications/MAMP/conf/apache/httpd.conf を編集する。自分の場合は /Applications/MAMP/htdocs以下全部で実行したいので以下の場所を変更。

    453行目付近

    Selec All Code:
        #AddHandler cgi-script .cgi
        AddHandler cgi-script .cgi .pl .pm ←追記

    httpd.confを編集したらMANPを再起動して設定を反映させる。

    CGI実行テスト

    /アプリケーション/MAMP/htdocs/ に test.cgiを作成する。

    Selec All Code:
    #!/usr/bin/env perl
    print "Content-type:text/html\n\n";
    print "Hello, World!\n";
    exit;

    test.cgi に実行権を与える。

    Selec All Code:
    $ cd /Applications/MANP/htdocs
    $ chmod 700 test.cgi

    webブラウザで http://localhost/test.cgi にアクセスして表示されたら成功。

    ちなみにMAMPの読み方はまんpーでいいんじゃないでしょうか?







    2011 12月12日

    PerlでPayPalのExpressCheckoutを実装するのにBusiness::PayPal::APIを使っているのだけれど、日本語(2byte文字)がうまく送信できない。

    UTF-8で送ろうが、フラグ付きにしようが、だ。

    散々悩んだ挙句、原因はSOAP::Liteが勝手にbase64エンコードするからだと判明。

    Business::PayPal::APIは内部でSOAP::Liteを使用していて、Asciiだとそのままなのだけれど、それ以外はbase64にエンコードする仕様の様子。

    前々から、例えば、OrderDescription に日本語を使うと上手くいかないと思っていたのだけれど、、、。
    仕方がないから Business::PayPal::API::ExpressCheckoutをカスタマイズする。

    /usr/lib/perl5/site_perl/5.8.8/Business/PayPal/API/ExpressCheckout.pm

    Selec All Code:
        ## add all the other fields
        for my $field ( keys %types ) {
    	next unless defined $args{$field};
     
            if( $field eq 'MaxAmount' ) {
                push @secrd, SOAP::Data->name( $field => $args{$field} )->type( $types{$field} )
                  ->attr( {currencyID => $currencyID, xmlns => $self->C_xmlns_ebay} );
            }
            ## 追記ココから
            elsif($field eq 'Address'){
                my @addr;
                my $hash = $args{$field};
                for my $f ( keys %$hash) {
                   push @addr,  SOAP::Data->name( $f )->type(string => $args{$field}{$f} );
                }
                my $obj = SOAP::Data->name( $field => \SOAP::Data->value( @addr ));
                push @secrd,$obj;
            }
            ## 追記ココまで
            else {
                push @secrd, SOAP::Data->name( $field => $args{$field} )->type( $types{$field} );
            }
        }

    SOAPなんて使ってたらダメだね…







    2011 7月30日

    DBIx::Custom – search.cpan.org
    DBIx-Custom-0.1705

    DBIx::Custom select メソッドの whereの項目を見ると様々な指定方法が出来ることが分かる。

    注意する点はStringを渡す時。

    Selec All Code:
    where => "url = 'http://hoge.com/huga.cgi?key=value' ",

    上のように条件に ? が含まれる場合、SQLの作成に失敗する。(DBIx::Custom::QueryBuilder::build_queryでかな?)

    ? がメタ文字として扱われるため?(\?とエスケープしてもダメ)

    Hashリファレンスで渡すと大丈夫です。

    Selec All Code:
    where => {url => 'http://hoge.com/huga.cgi?key=value' },

    これを踏まえてコードにすると、安全なのはこんな感じのコードになるのかな。

    Selec All Code:
        my $id = 1;
        my $url = 'http://hoge.com/huga.cgi?key=value';
        $result = $dbi->select(
            table   =>  'table_name',
            column  => [qw/title content url/],
            where => [
                        ["and", "{= id}", "url = :url", "update_time > SUBDATE( NOW(), interval 7 day )"],
                        { id => $id, url => $url},
            ],
        );

    ※ {= id} は “id = :id” とも書ける(url = :urlも同様)。あえて両方含めてみた。

    where にはDBIx::Custom::Whereオブジェクトも指定できますが、DBIx::Custom::Whereオブジェクトを生成する時にも同様で、? を含めた条件には注意が必要。

    追記:タグ機能は廃止予定だそうです。
    http://twitter.com/#!/perlcodesample/status/97162783644319744







    2011 7月29日

    perlモジュールのバージョンを一発で調べられるコマンド

    $ pmvers DBIx::Cutom
    0.168

    cpanmがインストールしてあれば

    $ cpanm pmvers

    でインストールできます。

    もうこんな事しなくていいんです。

    perl -MDBI -e 'print $DBIx::Custom::VERSION'






    2011 7月29日

    DBIx::Customが生SQL感覚でも使えてお気に入りなのだけれど、ちょっこしハマったのでメモ。

    DBIx::Custom – search.cpan.org

    MySQL(に限らないと思う)でwhereに関数を利用したい時は多々あると思います。
    例えば、更新時刻を見て7日以上古ければ選択しないという条件をwhereに指定したい時、

    Selec All Code:
    CREATE TABLE  `table` (
        `name` VARCHAR( 5 ) ,
        `update_time` TIMESTAMP
    )
     
    SELECT * FROM `table` WHERE update_time > SUBDATE(NOW(), INTERVAL 7 DAY);

    このようなSQLだとします。

    行の選択 select / DBIx::Custom リファレンス – サンプルコードによるPerl入門によれば、where句の設定は、

    Selec All Code:
    where => {title => 'Perl', author => 'Ken'}

    と、ハッシュリファレンスで渡すことになっています。

    = 以外での比較は DBIx::Custom::Whereオブジェクト を作成して渡すことになっているのですが、ハッシュリファレンスで SUBDATE(NOW(), interval 7 day) を渡すとうまくいかないので悩んでいました。

    append => ” で文字列を追加できるので、無理やり実装してみたのですが作者にツイートしてみたところ、

    twitterのキャプチャ

    がーん、そうなのか。恥ずかしい。。さらに、

    twitterのキャプチャ2

    がーん、DBIx::Custom::Where でも文字列が指定できたのか。。。(恥恥

    という事で、

    Selec All Code:
    use DBIx::Custom;
    my $dbi = DBIx::Custom->connect(
        ...........  端折ります
    );
    my $result = $dbi->select(
        table => 'table',
        where => 'create_time > SUBDATE(NOW(),  interval 7 day)', 
    );

    あるいは、

    Selec All Code:
    use DBIx::Custom;
    my $where = $dbi->where;
    $where->clause([
        'and', 'create_time > SUBDATE(NOW(),  interval 7 day)'
    ]);
    my $result = $dbi->select(
        table => 'table',
        where => $where, 
    );

    で、出来るって事なんですね。(ソース嫁!)

    id:perlcodesampleさんありがとうございました!
    DBIx::Customいいよー。

    ところで

    SYNOPSYSにあるinsertとかupdateとかが失敗するのはボクの日頃の行いが悪いせいでしょうか?

    Selec All Code:
        # Insert 
        $dbi->insert({title => 'Perl', author => 'Ken'}, table  => 'book');
     
        # Update 
        $dbi->update({title => 'Perl', author => 'Ken'}, table  => 'book',
          where  => {id => 5});
    Selec All Code:
        # Insert 
        $dbi->insert( param => {title => 'Perl', author => 'Ken'}, table  => 'book' );
     
        # Update 
        $dbi->update( param => {title => 'Perl', author => 'Ken'}, table  => 'book',
          where  => {id => 5} );

    だと性交いや、成功するのですが。
    param が必要??(だからソース嫁!)

    追記:DBIx::Customのバージョンが 0.168 だったからのようです…APIが追加された模様。