SlideShare une entreprise Scribd logo
1  sur  69
Télécharger pour lire hors ligne
「モダンPerl入門」の入門
   Songhee Han
   Kazuya Shono
自己紹介
                                              • 韓 松熙(song)
                                                      • 韓国出身のPerlエンジニア
                                                      • Perl歴4年目のnewbieです!
                                              • 荘野 和也(miniturbo)
                                                      • SBMカウンタの開発者
                                                      • Perl歴半年のnewbieです!




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.       2
サービス紹介
      • スクールガーディアン
            • 世界初の学校裏サイト・ネットいじめ対策サービス

            • インターネット上からネットいじめに関する書き込みなどを収集
              し学校に対策を提案するサービス

            • 元々手動でこなしていたサービスを自動化することに




9/17/2009          Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   3
プロジェクトの紹介
      • スクールガーディアンツール
            • 掲示板やプロフなどから特定の学校の学校裏サイトの情報を
              収集するツールです

            • 学校の先生が内容を確認できるように、サイト画面全体のスク
              リーンショットや投稿データを取得できます




9/17/2009          Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   4
モダンPerl との出会い
            2008年9月   2009年1月              2009年4月                    2009年7月           2009年9月



                      モダンPerl                    Catalyst5.8                         YAPC::Asia
                      入門発売                        リリース                                モダンPerl
                                                                                     の入門の入門
             モダン
            Perl界隈                             JPAセミナー#1
                                              モダンPerlの現場




                                                 Catalyst
            プロジェクト
                                企画             5.7ベースで                       Catalyst 5.8で開発
            スケジュール                             調査/設計




9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                5
Catalyst & API 設計
Presented by Songhee Han
アプリケーションの構成




9/17/2009     Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   7
アプリケーションの分割
      • Catalyst
            • SchoolG::Client                 (エンドユーザ機能)
            • SchoolG::Work                   (管理者機能)
      • ジョブ
            • SchoolG::Batch                  ( TheSchwartz Job )
      • 共通
            • SchoolG                         (共有モジュール/API)



9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   8
フォルダ構造
            app_root/
             SchoolG-Client/
              lib/
              root/                                                          CatalystApp
              script/
              template/
             SchoolG-Work/
              lib/
              root/                                                          CatalystApp
              script/
              template/
             SchoolG-Batch/
              lib/
              script/                                                            バッチ
              t/
             SchoolG/
              config/
              extlib/
              lib/                                                             共通部分
              script/
              t/
              template/




9/17/2009                      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   9
実装




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   10
使いたかった技術
      •     Catalyst 5.8 + Moose
      •     API
      •     Web::Scraper
      •     TheSchwartz
      •     local::lib




9/17/2009             Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   11
Catalyst 5.8
      • local::libで運用
            • 開発環境でCatalyst5.7と5.8を共存させたかった


      • Catalyst::UpgradingのPODを参考にした
            • Catalystをextendsしていた
            • Pluginは極力使わないようにした




9/17/2009          Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   12
最小限のPlugin
      • ログイン関連
            • Catalyst::Plugin::Authentication
            • Catalyst::Plugin::Authorization::Roles
      • Session関連
            • Catalyst::Plugin::Session
            • Catalyst::Plugin::Session::Store::Memcached
            • Catalyst::Plugin::Session::State::Cookie
      • その他
            • Catalyst::Plugin::FillInForm




9/17/2009                 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   13
API化までの試行錯誤




9/17/2009     Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   14
APIへの第一歩
      • モダンPerl入門
            これをより汎用的にして他のスクリプトからも呼べるようにするには、$c->model()
            が呼び出された時にCatalyst依存のMyApp::Model::Userではなく単体で
            動作するオブジェクトを返すようにしてしまえばいいのです。


                                                                        「モダンPerl入門」 より引用




9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.         15
Modelの分離
      • Controllerにロジックを書いていた時代
            • Controllerの見通しが悪くなっていった
      • Controllerからロジックを分離する
            • ロジックはModelに切り出した
            • 但し、ModelはCatalystに依存したまま
      • Modelからロジックを分離する
            • Model::Adaptorを利用してModelとロジックをマ
              ッピングさせた



9/17/2009           Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   16
Modelの分離
      • Model::Adaptorで一つ一つマッピングするの
        は意外と大変
      • Model::MultiAdaptorでつなぐようにした




9/17/2009     Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   17
Modelの分離(API)
            package SchoolG::Work::Model::API::Logic;

            use strict;
            use warnings;
            use parent 'Catalyst::Model::MultiAdaptor';

            1;




9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   18
Modelの分離(YAML)
            Model::API::Logic:
              package: 'SchoolG::API::Logic'
              lifecycle: Singleton
              except:
                - 'Plugin::Filter'




9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   19
Modelの分離はいったん完成
             でも画面を書いていくうちに、
             APIの中身がごちゃごちゃに…
                   これでAPI?
            分離するだけは何かが足りない…



9/17/2009       Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   20
API?
      • Wikipedia
            Application programming interface (API) is an interface in computer
            science that defines the ways by which an application program may request
            services from libraries and/or operating systems

            The API initialism may sometimes be used as a reference, not only to the
            full interface, but also to one function, or even a set of multiple APIs
            provided by an organization. Thus, the scope of meaning is usually
            determined by the person or document that
            communicates the information.
                                                                                            Wikipediaより引用




9/17/2009                      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                   21
なら、APIは自分たちなりに
                  定義して
              決めたらいいの?



9/17/2009      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   22
社内での議論(1)
      • 分離したロジックはなぜごちゃごちゃになっている?
            • APIモジュール群がうまく分類されていなくて、どこにどの処
              理が書いてあるのか見失いやすくなった
            • 結局ロジックを書く場所が変わっただけ?


      • 分離したロジックを整理していかなければいけない




9/17/2009          Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   23
社内での議論(1)
      • WebアプリケーションはDB処理が多い

      • 至るところで繰り返し呼び出されるDB処理(CRUD処
        理)と、一連の処理の流れ(ビジネスロジック)を整理す
        ることでAPIの見通しがよくなるのではないかと考えた

      • それぞれどこに、どのように書くべきか?




9/17/2009    Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   24
社内での議論(2)
            A案:API≒CRUD処理派

                 SchoolG               API                                CRUD処理


                                       Logic                              ビジネスロジック


                                       DBIC                               DBICの接続



            B案:API≒ビジネスロジック派

                 SchoolG               DBIC                               CRUD処理(DBICの接続)


                                       API                                ビジネスロジック




9/17/2009                  Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.       25
社内での議論(3)
      • APIは隠ぺい化された機能

      • CRUD処理も ビジネスロジックも、隠蔽化さ
        れた機能として(どのコンテキストからも呼び
        出せるように)実装していきたい

      • つまりCRUD処理もビジネスロジックもAPI!



9/17/2009    Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   26
社内での議論(4)


                 SchoolG          API                 Data                   CRUD処理


            最終
            案
                                                     Logic                   ビジネスロジック




9/17/2009            Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.         27
実装してフィードバック、
            また修正してフィードバック、
                  …
              出来上がってきた!



9/17/2009      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   28
API
                                                                              API::Data
      APIの構成                                                                  API::Logic
                                                                              API

      • API::Data
         • DBへの接続
         • SQLの発行
      • API::Logic
         • ビジネスロジック
         • Dataを呼び出してデータを取得・整形
      • API
      • API::Jobqueue
      • API::Plugin




9/17/2009       Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 29
API
                                                                          API::Data
                                                                          API::Logic
                                                                          API




                  API::Data




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 30
API
                                                                                API::Data

      API::Data                                                                 API::Logic
                                                                                API



        • 役割
            • DBへの接続とSQLの発行を行う
            • 子クラスにCRUD処理を記述する
        • 機能
            • レプリケーション管理
            • コネクションプーリング
            • 返値のデータ形式の統一
        • 実装のポイント
            • 子クラスはテーブル毎に作るようにした



9/17/2009         Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 31
API::DataとDBICのつなぎ方
      package SchoolG::API::Data;
      has _master_schema => (
          is       => 'rw',
          required => 1,
          isa      => 'DBIx::Class::Schema',
          default =>
             sub {
               # Singleton化した
               SchoolG::DBIC::Singleton->instance->_master
             }
      );
      sub master {
          my ( $self, $table_name ) = @_;
          $table_name ||= $self->_table_name;
          return $self->_master_schema
                      ->resultset($table_name);
      }

9/17/2009            Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   32
API::Dataのデータの返し方
      package SchoolG::API::Data;
      # DBICのsearchは直接利用せずに親クラス(このクラス)のsearchを利用する
      sub search {
          my ( $self, $args ) = @_;
          my $conditions = $args->{conditions};
          my $options    = $args->{options};
          # searchの場合はslaveのschemaを利用
          my $resultset =
            $self->slave->search( $conditions, $options );
          # DBICのオブジェクトではなくHashRefかArrayRefで返すようにした
          $resultset->result_class
               ('DBIx::Class::ResultClass::HashRefInflator');
          return
            exists $options->{page} && exists $options->{rows}
            ? {
                 result => [ $resultset->all ],
                 pager => $resultset->pager
              }
            : [ $resultset->all ];
      }
9/17/2009             Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   33
API
                                                                          API::Data
                                                                          API::Logic
                                                                          API




                 API::Logic




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 34
API
                                                                                    API::Data

      API::Logic                                                                    API::Logic
                                                                                    API



      • 役割
            • 子クラスにビジネスロジックを記述する
              • Catalyst のComponentにはビジネスロジックは極力書かない
              • CRUD処理はAPI::Dataに記述し、API::Logicから呼び出す
      • API::Logicの子クラスで行う処理の流れ
            • Validation処理
            • 一連のCRUD処理(トランザクション管理も含む)
            • CRUD処理結果の加工
      • 実装のポイント
            • Catalystアプリケーション及びジョブの両方からAPI::Logicを呼び出
              せるようにした




9/17/2009             Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 35
package SchoolG::API::Logic::ManageStaff;
      extends 'SchoolG::API::Logic';
      sub create {
          my ( $self, $args ) = @_;

            my $created_by = delete $args->{created_by};
            my $validation = $self->validate(
                $args->{columns}, 'create' );
            return $validation unless $validation->{success};

            delete $args->{columns}->{cancel};
            delete $args->{columns}->{submit};
            $args->{columns}->{staff_created_by} = $created_by;
            $args->{columns}->{staff_updated_by} = $created_by;

            my $txn = sub {
                $self->data('MasterStaff')->create($args);
            };
            $self->txn($txn);
      }

9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   36
API
                                                                          API::Data
                                                                          API::Logic
                                                                          API




                                API




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 37
API
                                                                                    API::Data
                                                                                    API::Logic

      API                                                                           API



      • 役割
            • API::DataとAPI::Logicの親クラス
      • 機能
            • API::DataとAPI::Logicのアクセサの提供
            • API::DataとAPI::Logicで共通メソッドの提供
      • 実装のポイント
            • ジョブからAPIを経由してAPI::DataとAPI::Logic両方を簡
              単に呼べるようにした




9/17/2009             Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                 38
API
                                                                                          API::Data

      APIの最終形                                                                             API::Logic
                                                                                          API



      Catalyst からも ジョブからもAPIを呼べる

                                                    API

                                                   Data
            Catalyst

              Job                                                                   DB
                                                  Logic




9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.                      39
実装:Catalystからの呼び出し




9/17/2009    Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   40
package SchoolG::Work::Controller::Manage::Staff::Create;

      sub execute : Local {
          my ( $self, $c ) = @_;

            my $result = $c->model('API::Logic::ManageStaff')
                ->create(
                {
                    columns    => $c->req->params,
                    created_by => $c->user->staff_seq
                }
            );

            $c->res->redirect( $c->uri_for('/manage/staff') );
      }




9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   41
package SchoolG::API::Logic::ManageStaff;
      extends 'SchoolG::API::Logic';
      sub create {
          my ( $self, $args ) = @_;

            my $created_by = delete $args->{created_by};
            my $validation = $self->validate(
                $args->{columns}, 'create' );
            return $validation unless $validation->{success};

            delete $args->{columns}->{cancel};
            delete $args->{columns}->{submit};
            $args->{columns}->{staff_created_by} = $created_by;
            $args->{columns}->{staff_updated_by} = $created_by;

            my $txn = sub {
                $self->data('MasterStaff')->create($args);
            };
            $self->txn($txn);
      }

9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   42
package SchoolG::API::Data::MasterStaff;

      use Moose;
      extends 'SchoolG::API::Data';

      sub BUILD {
          my $self = shift;
          $self->_table_name('MasterStaff');
          $self->_table_prefix('staff');
          $self->_default_conditions( {
            staff_delete => 0,
            staff_seq => { '>' => 1 }
          } );
          $self->_default_options(
            { order_by => [qw/staff_office/] }
          );
      }




9/17/2009            Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   43
package SchoolG::API::Data;
      use Moose;

      has _table_prefix => (
          is => 'rw',
          isa => 'Str',
      );

      sub create {
          my ( $self, $args ) = @_;

            my $prefix = $self->_table_prefix;
            my $columns = $args->{columns};
            my $result = $self->master->create($columns);
            return $result ?
              { success => 1 } : { success => 0 };
      }



9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   44
実装:ジョブからの呼び出し




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   45
package SchoolG::Batch::Job::CountTask;

      sub work {
          my ( $class, $job ) = @_;

            my $api    = SchoolG::API->new();

            my $result = $api->logic('CountTask')
                           ->get_profile_count( $job->arg );

            $job->completed;
      }




9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   46
package SchoolG::API::Logic::CountTask;
      extends 'SchoolG::API::Logic';

      sub get_profile_count {
          my ( $self, $args ) = @_;

            undef my $counts;
            return $counts if $args->{operation} == 3;

            $counts->{count_profile} =
              $self->data('DataProfile')->count_for_count_task(
                {
                    school_seq => $args->{school_seq},
                    status     => 0
                }
            );

            return $counts;
      }




9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   47
package SchoolG::API::Data::DataProfile;

      use Moose;
      extends 'SchoolG::API::Data';

      sub count_for_count_task {
          my ( $self, $args ) = @_;

            my $conditions;
            $conditions->{profile_school_seq} =
              $args->{school_seq};

            $self->SUPER::count(
              { conditions => $conditions }
            );
      }




9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   48
APIの設計・リファクタを振りかえって




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   49
APIを設計しながら
      • 機能単位の分割するのが難しかった
      • ルールをすべて守るのが難しかった
            • リファクタリング5回くらい!!!
      • まとまってきれいにかけた




9/17/2009         Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   50
まとめ
      • API設計
            • CRUD処理はAPI::Dataに、ビジネスロジックは
              API::Logicに分けることで見通しがよくなった
            • Catalystからもジョブからも呼べるような構成となった
      • Catalyst 5.8
            • 今回CatalystのComponentではMooseの機能は使って
              いない
            • Mooseの機能をCatalyst内で使わない限りは5.7とほとん
              ど同じように書くことができた




9/17/2009              Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   51
今後に向けて
      • 別のプロジェクトでも通用するのか試してみたい
      • ガイアックスでは今回APIをこのように考えて実装し
        てみました
      • 「APIってこんな考え方もあるよ」などの意見があれ
        ば是非教えて下さい
      • パフォーマンス向上などこれからも新しいことに挑戦
        していきます




9/17/2009    Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   52
参考にさせていただきました
      • Catalyst::Upgrading
            • http://search.cpan.org/~flora/Catalyst-Runtime-
              5.80011/lib/Catalyst/Upgrading.pod
      • モダンPerlの世界へようこそ - 第6回
        Catalyst::Upgrading:検証はお早めに
            • http://gihyo.jp/dev/serial/01/modern-perl/0006
      • Moosification: Catalyst 5.8に移行した際にちょっと
        気づいた事。
            • http://mt.endeworks.jp/d-6/2009/05/moosification-catalyst-
              58.html




9/17/2009                   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   53
まだ終わってないです!
            Perlじゃないって言われても
                 気にしません!




9/17/2009      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   54
おまけ:Canvasでスクリーンショット
   Presented by Kazuya Shono
スクリーンショットの要件
      • 学校裏サイトのスクリーンショッ
        トが欲しかった
      • サムネイルではなく、ページ全
        体のスクリーンショットが必要
        だった
      • 長いページでもページ全体を
        撮る必要があった

      • 実装にあたって、2つのアプ
        ローチがありました




9/17/2009      Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   56
アプローチ
      • Xvfb案
            • Xvfb(Xの仮想環境)にブラウザを立ち上げて、Xvfb
              自体をキャプチャ!
      • Canvas案
            • FirefoxのCanvas要素でWebページをキャプチャ!

      • まずはXvfbの実装から試してみることに!!




9/17/2009           Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   57
案①
      • Xvfbでキャプチャ!
            • XvfbにFirefoxを起動し、                                                   取得
              X Window Dumpで                                                      範囲
              ファイルとして保存する

      • …この案では、 Xの仮
      想環境の高さまでしかペ
      ージのキャプチャが取得
      できない!




9/17/2009            Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.    58
案②
      • Canvasでキャプチャ!
            • Firefoxで、Canvas要素
              へWebサイトを描画し、
              それをファイルとして保
              存する
                                                                                  取得
                                                                                  範囲
            • …コンテンツ量の多いサ
              イトで、メモリ不足になり、
              キャプチャが取得できな
              いときがある!




9/17/2009            Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.    59
案③
      • Canvasでキャプチャ!
                                                                                 取得
            • Canvas要素でスクリーン                                                     範囲
              ショットを取得
            • 工夫として、撮影領域の
              高さを固定し、分割して
              キャプチャするようにした

            • →高さを固定できるので、                                                       取得
              1回のキャプチャのメモリ                                                       範囲
              使用量の上限を固定でき
              る




9/17/2009           Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.    60
結果…
      • Canvas案を採用しました!
            • この案をもとに、開いたページのスクリーンショットを
              撮るFirefoxのアドオンを制作しました

            • Canvasでスクリーンショットを取得
            • XPCOMでディスクへファイルとして書き込み




9/17/2009         Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   61
実装




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   62
CanvasでWebページを描画
            • canvas要素を作成し、Webページを描画する
            • toDataURL()を用いて描画したデータの
              data:URLを取得する



      var canvas = window.document.createElement(‘canvas’);
      var ctx = canvas.getContext('2d');

      // Webページの描画
      ctx.drawWindow(window, X開始点, Y開始点,
           X終了点, Y終了点, ‘rgb(0,0,0)’);
      ctx.restore();

      // 描画したデータをBASE64エンコードしたdata:URLを取得
      var url = canvas.toDataURL(‘image/png’);


9/17/2009             Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   63
ファイルの保存
            • nsIURIオブジェクトの生成
            • nsILocalFileでファイルオブジェクトを生成
            • nsIWebBrowserPersistでファイルに保存する
      var Cc = Components.classes;
      var Ci = Components.interfaces;

      // URIオブジェクトの生成
      var URI = Cc['@mozilla.org/network/io-service;1']
        .getService(Ci.nsIIOService).newURI(url, null, null);

      // ファイルオブジェクトの生成
      var file = Cc["@mozilla.org/file/local;1"]
        .createInstance(Ci.nsILocalFile);
      file.initWithPath(保存先のファイルパス);

      // ファイルに保存
      var wbp = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
        .createInstance(Ci.nsIWebBrowserPersist);
      wbp.saveURI(url, null, null, null, null, file);

9/17/2009               Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   64
分割キャプチャ
              以上の実装を、ブラウザの高さで
              分割して、繰り返しキャプチャするようにした
      var     max = window.document.height;
      var     width = window.outerWidth;
      var     fromY = window.scrollY;
      var     height = window.innerHeight;

      while (fromY <= max) {
        var toY = (fromY + height) > max ?
          max : fromY + height;

            // キャプチャするメソッド
            capture(window, width, fromY, toY);
            if (fromY + height > max) break;

            fromY = toY;
      }
9/17/2009                  Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   65
実演
      • デモをご覧ください




9/17/2009     Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   66
参考にさせていただきました
      • SCRAPBLOG : canvas要素によるWebペー
        ジのスクリーンショット保存機能
            • http://www.xuldev.org/blog/?p=37
      • File I/O – MDC
            • https://developer.mozilla.org/ja/Code_snippets/File_I
              %2F%2FO




9/17/2009                Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   67
最後に告知




9/17/2009   Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   68
仲間募集中!
      • ガイアックスでは、小さなチームで新しい技術を積極的に取り入れながら
        自社プロダクトを開発しています。
      • 一緒にチャレンジし、成長していく意欲のある開発者を募集中です。




9/17/2009       Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.   69

Contenu connexe

En vedette

Codificação lossy do JPEG
Codificação lossy do JPEGCodificação lossy do JPEG
Codificação lossy do JPEGStanislaw Pusep
 
Kansai.pmと僕 - Kansaipm#14
Kansai.pmと僕 - Kansaipm#14 Kansai.pmと僕 - Kansaipm#14
Kansai.pmと僕 - Kansaipm#14 Kazuki KOMORI
 
Perl5環境構築 Kansaipm#13
Perl5環境構築 Kansaipm#13Perl5環境構築 Kansaipm#13
Perl5環境構築 Kansaipm#13Kazuki KOMORI
 
PHPerのためのPerl入門@ Kansai.pm#12
PHPerのためのPerl入門@ Kansai.pm#12PHPerのためのPerl入門@ Kansai.pm#12
PHPerのためのPerl入門@ Kansai.pm#12Kazuki KOMORI
 

En vedette (6)

Codificação lossy do JPEG
Codificação lossy do JPEGCodificação lossy do JPEG
Codificação lossy do JPEG
 
ExtJS
ExtJSExtJS
ExtJS
 
Kansai.pmと僕 - Kansaipm#14
Kansai.pmと僕 - Kansaipm#14 Kansai.pmと僕 - Kansaipm#14
Kansai.pmと僕 - Kansaipm#14
 
LWP + libcurl
LWP + libcurlLWP + libcurl
LWP + libcurl
 
Perl5環境構築 Kansaipm#13
Perl5環境構築 Kansaipm#13Perl5環境構築 Kansaipm#13
Perl5環境構築 Kansaipm#13
 
PHPerのためのPerl入門@ Kansai.pm#12
PHPerのためのPerl入門@ Kansai.pm#12PHPerのためのPerl入門@ Kansai.pm#12
PHPerのためのPerl入門@ Kansai.pm#12
 

Similaire à 「モダンPerl入門」の入門

Pylons ユーザのための Pyramid 移行ガイド
Pylons ユーザのための Pyramid 移行ガイドPylons ユーザのための Pyramid 移行ガイド
Pylons ユーザのための Pyramid 移行ガイドNozomu Kaneko
 
AndApp開発における全て #denatechcon
AndApp開発における全て #denatechconAndApp開発における全て #denatechcon
AndApp開発における全て #denatechconDeNA
 
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめ
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめ
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめTetsutaro Watanabe
 
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]David Buck
 
ネイティブ機能を利用する Webアプリの実例 ~PhoneGap×Rails~
ネイティブ機能を利用するWebアプリの実例~PhoneGap×Rails~ネイティブ機能を利用するWebアプリの実例~PhoneGap×Rails~
ネイティブ機能を利用する Webアプリの実例 ~PhoneGap×Rails~Daisuke Futatsumori
 
いまさら聞けない!HTML5超入門
いまさら聞けない!HTML5超入門いまさら聞けない!HTML5超入門
いまさら聞けない!HTML5超入門Monaca
 
PhoneGapの始め方
PhoneGapの始め方PhoneGapの始め方
PhoneGapの始め方akabana
 
MuleアプリケーションのCI/CD
MuleアプリケーションのCI/CDMuleアプリケーションのCI/CD
MuleアプリケーションのCI/CDMuleSoft Meetup Tokyo
 
Rubyプログラミング教育に対する取り組みと事例紹介
Rubyプログラミング教育に対する取り組みと事例紹介Rubyプログラミング教育に対する取り組みと事例紹介
Rubyプログラミング教育に対する取り組みと事例紹介Yasushi Ishikawa
 
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計アシアル株式会社
 
OCI serverless introduction
OCI serverless introductionOCI serverless introduction
OCI serverless introductionSuguruSugiyama
 
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけね
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけねGitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけね
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけねNaoto TAKAHASHI
 
CloudHubのログバックアップについて
CloudHubのログバックアップについてCloudHubのログバックアップについて
CloudHubのログバックアップについてMuleSoft Meetup Tokyo
 
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割技術選択とアーキテクトの役割
技術選択とアーキテクトの役割Toru Yamaguchi
 
EclipseCon Europe 2019 modeling report
EclipseCon Europe 2019 modeling reportEclipseCon Europe 2019 modeling report
EclipseCon Europe 2019 modeling reportAkira Tanaka
 
Oracle APEXユーザー会の紹介
Oracle APEXユーザー会の紹介Oracle APEXユーザー会の紹介
Oracle APEXユーザー会の紹介Nakakoshi Yuji
 

Similaire à 「モダンPerl入門」の入門 (20)

Pylons ユーザのための Pyramid 移行ガイド
Pylons ユーザのための Pyramid 移行ガイドPylons ユーザのための Pyramid 移行ガイド
Pylons ユーザのための Pyramid 移行ガイド
 
AndApp開発における全て #denatechcon
AndApp開発における全て #denatechconAndApp開発における全て #denatechcon
AndApp開発における全て #denatechcon
 
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめ
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめ
ML Ops NYC 19 & Strata Data Conference 2019 NewYork 注目セッションまとめ
 
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]
Ahead-of-Time Compilation with JDK 9 [Java Day Tokyo 2017 D1-A1]
 
ネイティブ機能を利用する Webアプリの実例 ~PhoneGap×Rails~
ネイティブ機能を利用するWebアプリの実例~PhoneGap×Rails~ネイティブ機能を利用するWebアプリの実例~PhoneGap×Rails~
ネイティブ機能を利用する Webアプリの実例 ~PhoneGap×Rails~
 
Spring tools4
Spring tools4Spring tools4
Spring tools4
 
いまさら聞けない!HTML5超入門
いまさら聞けない!HTML5超入門いまさら聞けない!HTML5超入門
いまさら聞けない!HTML5超入門
 
CakePHPとYii_エンジニア勉強会20130820
CakePHPとYii_エンジニア勉強会20130820CakePHPとYii_エンジニア勉強会20130820
CakePHPとYii_エンジニア勉強会20130820
 
PhoneGapの始め方
PhoneGapの始め方PhoneGapの始め方
PhoneGapの始め方
 
MuleアプリケーションのCI/CD
MuleアプリケーションのCI/CDMuleアプリケーションのCI/CD
MuleアプリケーションのCI/CD
 
Rubyプログラミング教育に対する取り組みと事例紹介
Rubyプログラミング教育に対する取り組みと事例紹介Rubyプログラミング教育に対する取り組みと事例紹介
Rubyプログラミング教育に対する取り組みと事例紹介
 
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_cccSpring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
 
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
 
OCI serverless introduction
OCI serverless introductionOCI serverless introduction
OCI serverless introduction
 
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけね
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけねGitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけね
GitHubのリポジトリ(32個)を 覗いてみよう。 ただし、READMEだけね
 
CloudHubのログバックアップについて
CloudHubのログバックアップについてCloudHubのログバックアップについて
CloudHubのログバックアップについて
 
技術選択とアーキテクトの役割
技術選択とアーキテクトの役割技術選択とアーキテクトの役割
技術選択とアーキテクトの役割
 
EclipseCon Europe 2019 modeling report
EclipseCon Europe 2019 modeling reportEclipseCon Europe 2019 modeling report
EclipseCon Europe 2019 modeling report
 
Api
ApiApi
Api
 
Oracle APEXユーザー会の紹介
Oracle APEXユーザー会の紹介Oracle APEXユーザー会の紹介
Oracle APEXユーザー会の紹介
 

Dernier

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 

Dernier (9)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 

「モダンPerl入門」の入門

  • 1. 「モダンPerl入門」の入門 Songhee Han Kazuya Shono
  • 2. 自己紹介 • 韓 松熙(song) • 韓国出身のPerlエンジニア • Perl歴4年目のnewbieです! • 荘野 和也(miniturbo) • SBMカウンタの開発者 • Perl歴半年のnewbieです! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 2
  • 3. サービス紹介 • スクールガーディアン • 世界初の学校裏サイト・ネットいじめ対策サービス • インターネット上からネットいじめに関する書き込みなどを収集 し学校に対策を提案するサービス • 元々手動でこなしていたサービスを自動化することに 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 3
  • 4. プロジェクトの紹介 • スクールガーディアンツール • 掲示板やプロフなどから特定の学校の学校裏サイトの情報を 収集するツールです • 学校の先生が内容を確認できるように、サイト画面全体のスク リーンショットや投稿データを取得できます 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 4
  • 5. モダンPerl との出会い 2008年9月 2009年1月 2009年4月 2009年7月 2009年9月 モダンPerl Catalyst5.8 YAPC::Asia 入門発売 リリース モダンPerl の入門の入門 モダン Perl界隈 JPAセミナー#1 モダンPerlの現場 Catalyst プロジェクト 企画 5.7ベースで Catalyst 5.8で開発 スケジュール 調査/設計 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 5
  • 6. Catalyst & API 設計 Presented by Songhee Han
  • 7. アプリケーションの構成 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 7
  • 8. アプリケーションの分割 • Catalyst • SchoolG::Client (エンドユーザ機能) • SchoolG::Work (管理者機能) • ジョブ • SchoolG::Batch ( TheSchwartz Job ) • 共通 • SchoolG (共有モジュール/API) 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 8
  • 9. フォルダ構造 app_root/ SchoolG-Client/ lib/ root/ CatalystApp script/ template/ SchoolG-Work/ lib/ root/ CatalystApp script/ template/ SchoolG-Batch/ lib/ script/ バッチ t/ SchoolG/ config/ extlib/ lib/ 共通部分 script/ t/ template/ 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 9
  • 10. 実装 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 10
  • 11. 使いたかった技術 • Catalyst 5.8 + Moose • API • Web::Scraper • TheSchwartz • local::lib 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 11
  • 12. Catalyst 5.8 • local::libで運用 • 開発環境でCatalyst5.7と5.8を共存させたかった • Catalyst::UpgradingのPODを参考にした • Catalystをextendsしていた • Pluginは極力使わないようにした 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 12
  • 13. 最小限のPlugin • ログイン関連 • Catalyst::Plugin::Authentication • Catalyst::Plugin::Authorization::Roles • Session関連 • Catalyst::Plugin::Session • Catalyst::Plugin::Session::Store::Memcached • Catalyst::Plugin::Session::State::Cookie • その他 • Catalyst::Plugin::FillInForm 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 13
  • 14. API化までの試行錯誤 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 14
  • 15. APIへの第一歩 • モダンPerl入門 これをより汎用的にして他のスクリプトからも呼べるようにするには、$c->model() が呼び出された時にCatalyst依存のMyApp::Model::Userではなく単体で 動作するオブジェクトを返すようにしてしまえばいいのです。 「モダンPerl入門」 より引用 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 15
  • 16. Modelの分離 • Controllerにロジックを書いていた時代 • Controllerの見通しが悪くなっていった • Controllerからロジックを分離する • ロジックはModelに切り出した • 但し、ModelはCatalystに依存したまま • Modelからロジックを分離する • Model::Adaptorを利用してModelとロジックをマ ッピングさせた 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 16
  • 17. Modelの分離 • Model::Adaptorで一つ一つマッピングするの は意外と大変 • Model::MultiAdaptorでつなぐようにした 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 17
  • 18. Modelの分離(API) package SchoolG::Work::Model::API::Logic; use strict; use warnings; use parent 'Catalyst::Model::MultiAdaptor'; 1; 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 18
  • 19. Modelの分離(YAML) Model::API::Logic: package: 'SchoolG::API::Logic' lifecycle: Singleton except: - 'Plugin::Filter' 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 19
  • 20. Modelの分離はいったん完成 でも画面を書いていくうちに、 APIの中身がごちゃごちゃに… これでAPI? 分離するだけは何かが足りない… 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 20
  • 21. API? • Wikipedia Application programming interface (API) is an interface in computer science that defines the ways by which an application program may request services from libraries and/or operating systems The API initialism may sometimes be used as a reference, not only to the full interface, but also to one function, or even a set of multiple APIs provided by an organization. Thus, the scope of meaning is usually determined by the person or document that communicates the information. Wikipediaより引用 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 21
  • 22. なら、APIは自分たちなりに 定義して 決めたらいいの? 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 22
  • 23. 社内での議論(1) • 分離したロジックはなぜごちゃごちゃになっている? • APIモジュール群がうまく分類されていなくて、どこにどの処 理が書いてあるのか見失いやすくなった • 結局ロジックを書く場所が変わっただけ? • 分離したロジックを整理していかなければいけない 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 23
  • 24. 社内での議論(1) • WebアプリケーションはDB処理が多い • 至るところで繰り返し呼び出されるDB処理(CRUD処 理)と、一連の処理の流れ(ビジネスロジック)を整理す ることでAPIの見通しがよくなるのではないかと考えた • それぞれどこに、どのように書くべきか? 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 24
  • 25. 社内での議論(2) A案:API≒CRUD処理派 SchoolG API CRUD処理 Logic ビジネスロジック DBIC DBICの接続 B案:API≒ビジネスロジック派 SchoolG DBIC CRUD処理(DBICの接続) API ビジネスロジック 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 25
  • 26. 社内での議論(3) • APIは隠ぺい化された機能 • CRUD処理も ビジネスロジックも、隠蔽化さ れた機能として(どのコンテキストからも呼び 出せるように)実装していきたい • つまりCRUD処理もビジネスロジックもAPI! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 26
  • 27. 社内での議論(4) SchoolG API Data CRUD処理 最終 案 Logic ビジネスロジック 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 27
  • 28. 実装してフィードバック、 また修正してフィードバック、 … 出来上がってきた! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 28
  • 29. API API::Data APIの構成 API::Logic API • API::Data • DBへの接続 • SQLの発行 • API::Logic • ビジネスロジック • Dataを呼び出してデータを取得・整形 • API • API::Jobqueue • API::Plugin 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 29
  • 30. API API::Data API::Logic API API::Data 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 30
  • 31. API API::Data API::Data API::Logic API • 役割 • DBへの接続とSQLの発行を行う • 子クラスにCRUD処理を記述する • 機能 • レプリケーション管理 • コネクションプーリング • 返値のデータ形式の統一 • 実装のポイント • 子クラスはテーブル毎に作るようにした 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 31
  • 32. API::DataとDBICのつなぎ方 package SchoolG::API::Data; has _master_schema => ( is => 'rw', required => 1, isa => 'DBIx::Class::Schema', default => sub { # Singleton化した SchoolG::DBIC::Singleton->instance->_master } ); sub master { my ( $self, $table_name ) = @_; $table_name ||= $self->_table_name; return $self->_master_schema ->resultset($table_name); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 32
  • 33. API::Dataのデータの返し方 package SchoolG::API::Data; # DBICのsearchは直接利用せずに親クラス(このクラス)のsearchを利用する sub search { my ( $self, $args ) = @_; my $conditions = $args->{conditions}; my $options = $args->{options}; # searchの場合はslaveのschemaを利用 my $resultset = $self->slave->search( $conditions, $options ); # DBICのオブジェクトではなくHashRefかArrayRefで返すようにした $resultset->result_class ('DBIx::Class::ResultClass::HashRefInflator'); return exists $options->{page} && exists $options->{rows} ? { result => [ $resultset->all ], pager => $resultset->pager } : [ $resultset->all ]; } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 33
  • 34. API API::Data API::Logic API API::Logic 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 34
  • 35. API API::Data API::Logic API::Logic API • 役割 • 子クラスにビジネスロジックを記述する • Catalyst のComponentにはビジネスロジックは極力書かない • CRUD処理はAPI::Dataに記述し、API::Logicから呼び出す • API::Logicの子クラスで行う処理の流れ • Validation処理 • 一連のCRUD処理(トランザクション管理も含む) • CRUD処理結果の加工 • 実装のポイント • Catalystアプリケーション及びジョブの両方からAPI::Logicを呼び出 せるようにした 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 35
  • 36. package SchoolG::API::Logic::ManageStaff; extends 'SchoolG::API::Logic'; sub create { my ( $self, $args ) = @_; my $created_by = delete $args->{created_by}; my $validation = $self->validate( $args->{columns}, 'create' ); return $validation unless $validation->{success}; delete $args->{columns}->{cancel}; delete $args->{columns}->{submit}; $args->{columns}->{staff_created_by} = $created_by; $args->{columns}->{staff_updated_by} = $created_by; my $txn = sub { $self->data('MasterStaff')->create($args); }; $self->txn($txn); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 36
  • 37. API API::Data API::Logic API API 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 37
  • 38. API API::Data API::Logic API API • 役割 • API::DataとAPI::Logicの親クラス • 機能 • API::DataとAPI::Logicのアクセサの提供 • API::DataとAPI::Logicで共通メソッドの提供 • 実装のポイント • ジョブからAPIを経由してAPI::DataとAPI::Logic両方を簡 単に呼べるようにした 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 38
  • 39. API API::Data APIの最終形 API::Logic API Catalyst からも ジョブからもAPIを呼べる API Data Catalyst Job DB Logic 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 39
  • 40. 実装:Catalystからの呼び出し 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 40
  • 41. package SchoolG::Work::Controller::Manage::Staff::Create; sub execute : Local { my ( $self, $c ) = @_; my $result = $c->model('API::Logic::ManageStaff') ->create( { columns => $c->req->params, created_by => $c->user->staff_seq } ); $c->res->redirect( $c->uri_for('/manage/staff') ); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 41
  • 42. package SchoolG::API::Logic::ManageStaff; extends 'SchoolG::API::Logic'; sub create { my ( $self, $args ) = @_; my $created_by = delete $args->{created_by}; my $validation = $self->validate( $args->{columns}, 'create' ); return $validation unless $validation->{success}; delete $args->{columns}->{cancel}; delete $args->{columns}->{submit}; $args->{columns}->{staff_created_by} = $created_by; $args->{columns}->{staff_updated_by} = $created_by; my $txn = sub { $self->data('MasterStaff')->create($args); }; $self->txn($txn); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 42
  • 43. package SchoolG::API::Data::MasterStaff; use Moose; extends 'SchoolG::API::Data'; sub BUILD { my $self = shift; $self->_table_name('MasterStaff'); $self->_table_prefix('staff'); $self->_default_conditions( { staff_delete => 0, staff_seq => { '>' => 1 } } ); $self->_default_options( { order_by => [qw/staff_office/] } ); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 43
  • 44. package SchoolG::API::Data; use Moose; has _table_prefix => ( is => 'rw', isa => 'Str', ); sub create { my ( $self, $args ) = @_; my $prefix = $self->_table_prefix; my $columns = $args->{columns}; my $result = $self->master->create($columns); return $result ? { success => 1 } : { success => 0 }; } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 44
  • 45. 実装:ジョブからの呼び出し 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 45
  • 46. package SchoolG::Batch::Job::CountTask; sub work { my ( $class, $job ) = @_; my $api = SchoolG::API->new(); my $result = $api->logic('CountTask') ->get_profile_count( $job->arg ); $job->completed; } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 46
  • 47. package SchoolG::API::Logic::CountTask; extends 'SchoolG::API::Logic'; sub get_profile_count { my ( $self, $args ) = @_; undef my $counts; return $counts if $args->{operation} == 3; $counts->{count_profile} = $self->data('DataProfile')->count_for_count_task( { school_seq => $args->{school_seq}, status => 0 } ); return $counts; } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 47
  • 48. package SchoolG::API::Data::DataProfile; use Moose; extends 'SchoolG::API::Data'; sub count_for_count_task { my ( $self, $args ) = @_; my $conditions; $conditions->{profile_school_seq} = $args->{school_seq}; $self->SUPER::count( { conditions => $conditions } ); } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 48
  • 49. APIの設計・リファクタを振りかえって 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 49
  • 50. APIを設計しながら • 機能単位の分割するのが難しかった • ルールをすべて守るのが難しかった • リファクタリング5回くらい!!! • まとまってきれいにかけた 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 50
  • 51. まとめ • API設計 • CRUD処理はAPI::Dataに、ビジネスロジックは API::Logicに分けることで見通しがよくなった • Catalystからもジョブからも呼べるような構成となった • Catalyst 5.8 • 今回CatalystのComponentではMooseの機能は使って いない • Mooseの機能をCatalyst内で使わない限りは5.7とほとん ど同じように書くことができた 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 51
  • 52. 今後に向けて • 別のプロジェクトでも通用するのか試してみたい • ガイアックスでは今回APIをこのように考えて実装し てみました • 「APIってこんな考え方もあるよ」などの意見があれ ば是非教えて下さい • パフォーマンス向上などこれからも新しいことに挑戦 していきます 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 52
  • 53. 参考にさせていただきました • Catalyst::Upgrading • http://search.cpan.org/~flora/Catalyst-Runtime- 5.80011/lib/Catalyst/Upgrading.pod • モダンPerlの世界へようこそ - 第6回 Catalyst::Upgrading:検証はお早めに • http://gihyo.jp/dev/serial/01/modern-perl/0006 • Moosification: Catalyst 5.8に移行した際にちょっと 気づいた事。 • http://mt.endeworks.jp/d-6/2009/05/moosification-catalyst- 58.html 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 53
  • 54. まだ終わってないです! Perlじゃないって言われても 気にしません! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 54
  • 56. スクリーンショットの要件 • 学校裏サイトのスクリーンショッ トが欲しかった • サムネイルではなく、ページ全 体のスクリーンショットが必要 だった • 長いページでもページ全体を 撮る必要があった • 実装にあたって、2つのアプ ローチがありました 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 56
  • 57. アプローチ • Xvfb案 • Xvfb(Xの仮想環境)にブラウザを立ち上げて、Xvfb 自体をキャプチャ! • Canvas案 • FirefoxのCanvas要素でWebページをキャプチャ! • まずはXvfbの実装から試してみることに!! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 57
  • 58. 案① • Xvfbでキャプチャ! • XvfbにFirefoxを起動し、 取得 X Window Dumpで 範囲 ファイルとして保存する • …この案では、 Xの仮 想環境の高さまでしかペ ージのキャプチャが取得 できない! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 58
  • 59. 案② • Canvasでキャプチャ! • Firefoxで、Canvas要素 へWebサイトを描画し、 それをファイルとして保 存する 取得 範囲 • …コンテンツ量の多いサ イトで、メモリ不足になり、 キャプチャが取得できな いときがある! 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 59
  • 60. 案③ • Canvasでキャプチャ! 取得 • Canvas要素でスクリーン 範囲 ショットを取得 • 工夫として、撮影領域の 高さを固定し、分割して キャプチャするようにした • →高さを固定できるので、 取得 1回のキャプチャのメモリ 範囲 使用量の上限を固定でき る 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 60
  • 61. 結果… • Canvas案を採用しました! • この案をもとに、開いたページのスクリーンショットを 撮るFirefoxのアドオンを制作しました • Canvasでスクリーンショットを取得 • XPCOMでディスクへファイルとして書き込み 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 61
  • 62. 実装 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 62
  • 63. CanvasでWebページを描画 • canvas要素を作成し、Webページを描画する • toDataURL()を用いて描画したデータの data:URLを取得する var canvas = window.document.createElement(‘canvas’); var ctx = canvas.getContext('2d'); // Webページの描画 ctx.drawWindow(window, X開始点, Y開始点, X終了点, Y終了点, ‘rgb(0,0,0)’); ctx.restore(); // 描画したデータをBASE64エンコードしたdata:URLを取得 var url = canvas.toDataURL(‘image/png’); 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 63
  • 64. ファイルの保存 • nsIURIオブジェクトの生成 • nsILocalFileでファイルオブジェクトを生成 • nsIWebBrowserPersistでファイルに保存する var Cc = Components.classes; var Ci = Components.interfaces; // URIオブジェクトの生成 var URI = Cc['@mozilla.org/network/io-service;1'] .getService(Ci.nsIIOService).newURI(url, null, null); // ファイルオブジェクトの生成 var file = Cc["@mozilla.org/file/local;1"] .createInstance(Ci.nsILocalFile); file.initWithPath(保存先のファイルパス); // ファイルに保存 var wbp = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'] .createInstance(Ci.nsIWebBrowserPersist); wbp.saveURI(url, null, null, null, null, file); 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 64
  • 65. 分割キャプチャ 以上の実装を、ブラウザの高さで 分割して、繰り返しキャプチャするようにした var max = window.document.height; var width = window.outerWidth; var fromY = window.scrollY; var height = window.innerHeight; while (fromY <= max) { var toY = (fromY + height) > max ? max : fromY + height; // キャプチャするメソッド capture(window, width, fromY, toY); if (fromY + height > max) break; fromY = toY; } 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 65
  • 66. 実演 • デモをご覧ください 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 66
  • 67. 参考にさせていただきました • SCRAPBLOG : canvas要素によるWebペー ジのスクリーンショット保存機能 • http://www.xuldev.org/blog/?p=37 • File I/O – MDC • https://developer.mozilla.org/ja/Code_snippets/File_I %2F%2FO 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 67
  • 68. 最後に告知 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 68
  • 69. 仲間募集中! • ガイアックスでは、小さなチームで新しい技術を積極的に取り入れながら 自社プロダクトを開発しています。 • 一緒にチャレンジし、成長していく意欲のある開発者を募集中です。 9/17/2009 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 69