タグ別アーカイブ: Groovy

[perl] MOP(メタオブジェクトプロトコル)について調べてみた


プログラミングのレベルを1つステップアップするためにメタプログラミングについて調査してみた。 メタプログラミングについては以下の書籍が有名だと思います。。この本はRubyをベースに書かれています。 実は読んだことがないのですが、次に読もう!!

MOP周りの用語

この記事の内容に書かれていることを抜粋
MooseとClass::MOPでメタプログラミング始めた

  • メタプログラミング
    ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法

  • MOP(メタオブジェクトプロトコル)
    メタクラスを通してオブジェクトシステムへアクセスするAPI

  • メタクラス
    クラスの振る舞いを定義したクラスでイントロスペクション(introspection)とインターセッション(itercession)を備える

  • イントロスペクション
    オブジェクトの属性を得る能力 ex) 何のクラスを継承しているかとか、何のメソッドを持ってるかとか

  • インターセッション
    オブジェクトの振る舞いに変更を加える能力 ex) 親クラスを変更するとか、メソッドを追加するとか

メタプログラミングについて

メタプログラミングとはよく「プログラムをプログラムすること」と言われますが、どういうことでしょう?!
まつもとさんの書かれた記事にほぼ書いているのですが、
まつもと直伝 プログラミングのオキテ 第6回メタプログラミング

Perl の Mooseで説明すると、次のコードで説明できる。

■ MooseでHogeモジュール定義、mainで利用する

package Hoge;
use Moose;

has 'message' => (
    is => 'rw',
    required => 1,
);

# Hogeを利用するためのmainモジュール
package main;

my $obj = Hoge->new(message => "HOGE MESSAGE");
print $obj->message;   # HOGE MESSAGE

Hoge を new して message という属性(アトリビュート)のアクアクセサメソッドをつかって属性(アトリビュート)を設定したり、呼び出したりしている。ここでいう「has」メソッドが メタプログラミングされたメソッド となる。Mooseを定義することで自動で「new」メソッドができ、hasメソッドを書くことで message のセッター、ゲッターが暗黙的に利用できる状態になる。
このことをメタプログラミングと言って、「has」メソッドなど、 動的にオブジェクトやクラスにメソッドや属性を追加するための API を MOP という。そのMOPを提供するためのクラスをメタクラスという。
Perlでは Class::MOP が提供する。

Class::MOPを利用してみる

先ほどのHogeクラスをベースClass::MOPを使って動的にメソッドや属性を差し込む処理は以下の様な感じになります。

use strict;
use warnings;

package Hoge;
use Moose;

has 'message' => (
    is => 'rw',
    required => 1,
);

# このMooseのHogeクラスをClass::MOPのみでも作成することができる
# my $person_meta = Class::MOP::Class->create('Person');
#
# $person_meta->add_attribute(
#     'name',
#     accessor => 'name',
# );

##### ここから差し込むための処理 #####

package main;
use Class::MOP;

my $meta = Hoge->meta;  # [1] Hogeのメタクラスを取得

$meta->add_attribute(   # [2] nameという属性とアクセサメソッドの追加
    'name',
    accessor => 'name',
);

$meta->add_method(describe => sub { # [3] describeメソッドの追加
    my $self = shift;
    return "Name: ".$self->name.",  Message: ".$self->message;
});

my $hoge = Hoge->new(message => "I like soccer.", name => "YUSABANA");
  # オブジェクトの生成は以下のように$metaを使っても生成できる
  # $meta->new_object(message => "I like soccer.", name => "YUSABANA");

# 差し込んだメソッドdescribeを実行する
print $hoge->describe."\n";  # [4] Name: YUSABANA,  Message: I like soccer.

  • コード上[1]でHogeモジュールのメタクラスを取得する。
    このメタクラスを操作することで色々出来る。
  • コード上[2]は属性とアクセサメソッドを追加している。
  • コード上[3]はメソッドを追加している。
  • コード上[4]は追加したメソッドを実行して、画面出力する。

MOPを使えばこのように動的に処理を差し込むことができる。
Mooseの hasメソッドを定義している所でも add_attribute とかを使っているんだろ-なと予想できますねー!まだ、実際にコードは見ていないので確実ではないのですが。。。

  1. Class::MOP::Class – クラスに対するプロトコル
  2. Class::MOP::Attribute – アトリビュートに対するプロトコル
  3. Class::MOP::Method – メソッドに対するプロトコル
  4. Class::MOP::Instance – クラスのインスタンス生成に対するプロトコル

Moose::Util::TypeConstraints を使うと更に便利そう
http://idocsq.net/page/370

余談(Groovyでのメタプログラミング例)

■Stringクラスにhogeというメソッドを追加している。

String.metaClass.hoge = {->
    delegate.equals("hoge") ? true : false
}

println "hog".hoge()  //=> false
println "hoge".hoge() //=> true

TDDBC大阪3.0外伝 参加しました!


2013年はじめのTDD Boot Camp in 大阪 外伝
開催日:2013年01月13日

午前は講演、午後は演習(ペアプロ)の2段構成でした。 10時から18時までと長丁場でしたが本当に楽しかったし、周りの皆さんと色々話もできてモチベーションが上がった!!


午前の講演時のメモ

いろふさん(@irof)、渡辺さん(@shuji_w6e : 資料)のお話を聞きました!

テストの価値は失敗することにある.

  • テストを失敗させる
    • 失敗するバグを埋め込む
      ちゃんと失敗してくれる、 失敗は最小、 失敗をわかりやすく

  • 他人の書いたテストはわかりづらい
    • テストはわかりづらいだから当たり前にしよう
    • 特別なことを当たり前にする

あたりまえのこと(特別なことはない)

  • テストは落ちるもの
  • テストは読みにくいもの

TDDは開発手法

良いプログラムは開発できるが、良いシステムを開発できるわけじゃない。
TDDはテストリストが起点
良いシステム = 顧客の求めるシステム

「何を構築するか?」を考える
顧客の言葉を使ったシステムの使い方
ユースケースユーザストーリ
システムの外部的な振る舞い

ユースケース駆動開発

ユースケースを開発の起点として定義する。

  • システムとユーザインタラクションを記述
  • 一行で一つのアクション
  • 〜すると記述(できるは避ける)

外部設計 => システムを外から見た時の利用者視点

ユースケースから実装を導く

  • ロバストネス分析
    バウンダリ
    コントローラ
    エンティティ

ユースケース中の名詞 -> ドメイン として定義
ユースケース中の動詞 -> メソッド として定義

抽象的なユースケースのシナリオから、具体的な例として変更する => 具体的な値を入れることでユースケースから受け入れテスト(機能テスト)を導く事ができる。ユースケースを用いることでシステム全体を設計する

(例)自動販売機にお金を入れる => 自動販売機に100円入れる


午後の演習

@oota_kenさんと@kyon_mmさんとペアを組ませて頂きました。Groovyを触ってコツを掴んだ気がします。新しい言語でコードを書くときはいつもプログラミングは楽しいなーと感じます。
そして、GroovyとSpockはホントテストが簡潔に書けると実感。これは覚えるべきだなと思いました!!

演習の時のコードをアップしてもらいました。TDDBC Osaka Groovy

和田さんのペアプロでのレビュー

パラレルチェンジ(でかいリファクタリングの時に有効となる方法)でリファクタリングをした。
パラレルチェンジとは(參考

変更箇所が多数ある場合に、リファクタリング前のコードとリファクタリング後のコードを同居させ、1箇所ずつ変更するごとにテストコードで確認しながらリファクタリング後のコードへ移行させていく。

演習中でのパラレルチェンジをする流れ
・お金の扱いをInteger から Moneyクラスにする
・メソッドオーバーロード
・Integerで扱うところをなくしてMoneyを使うことにする

余談(イベント中で印象に残ったこと)

@kyon_mmさんと何気なく話していた時に話していた内容がとても刺激をうけた!!!!

「(@kyon_mm)今日は4時間で20数コミットかー、普段は60コミットくらいはしているけどなー」・・・
なんだって!!!コミット数が全てを物語っていると思う。自分は短時間でこんなにコードに変更を加えた経験はないし、いったとしても4時間で20コミットまで行くか行かないかだと思う。。。こういう所が差なんだろうなーと。

これからは技術書を読むことに加えて、もっとコードに戯れて楽しんでいけるようにしたいなー!!
いろんなコードをコミットしまくれる1年にしたい!

TDDBC OSAKA1.0へ参加しました!


 

2012年6月2日 TDDBootCampへ参加しました。

和田さんのセッションから始まり、ワークショップでTDDを実践し、夜の懇親会は闇LTでとてもサイコーな1日をすごせました。

特にGroovyには魅了されました。前から気になっていたのですが、Spockの素晴らしさが目に見えて凄いと思いました。

GrailsとかGraidleとかGroovy関連はなんか熱いっす!! これはもう始めましょう。。

そしてグリーンバンドも手に入れました。

今日からグリーンな男を目指してがんばろっと

以下、メモをまとめます。
  • 和田卓人さんのセッション

ソフトウェア開発の3本柱(三脚椅子)

・バージョン管理

・テスティング

・自動化(自働化)

人間ができることをする(デプロイなどの同じ作業は機械が向いている)。

基本的に自動で動かし通知方法を ツイッター、IRC、スカイプなどを通して人間に伝える。

人間がPullすることをなくし、機械がPush出来るようにする。

※バージョン管理が基本 これはソフトウェア開発の前提条件。


Testとは

・Developer Testing(開発者 開発促進) <ーTDDBCの対象

・CustomerTesting(顧客 進捗確認)

・QATesting(品質保証担当者 品質保証)

 

TDDのサイクル

1.テストを書き

2.そのテストを実行して失敗させ(Red)

3.目的のコードを書き

4.1で書いたテストを成功させ(Green)

5.テストが通るままでリファクタリングを行う(Refactor)

6.1〜5を繰り返す

 

黄金の回転

小さくはじめる

red, green, refactor を回す

 

TDDの心構え

1つずつ 少しずつ(大きい問題を小さく分割すること)

複数を相手にしない。(ひとりずつ対処する) 複数のテストを同時には書かない

素早くまわす(自分が何をするかがぼやけている場合は素早く回せない。) <ーこれが難しい。。と思う

不安に思うことについてテストを書く!

テストは目的じゃなくて手段(不安の克服健康体の維持)

 

テスト駆動開発とは何か

「健康」

変化に対応するのは健康体のコード

変化に対応するのは健康体のチーム

 

テストと製品コードについて

テストコードが正しいことはどうやって確認する?

テストコードと製品コードのつなぎ部分を確認する(テストコードの正しさは製品コードで確かめる)

そのために仮実装を行う。(必ず通る定数などを返すなど)

三角測量??

仮実装で通った値とは違う値を入れて確認してみる

テストコード自体はゴールから書く

何もない状態からテストをはじめるには。。

今回の自販機の課題であれば、何もない状態から表示するということを行う。(何もない状態で0を表示する)

 

最近のテストフレームワークは入れ子(ネスト)でかける Junit (Enclosed)

http://blog.livedoor.jp/ryu22e/archives/cat_50184887.html

テスト駆動に慣れてくると細かい単位のテストばかりではなく、大きな意味で、テストの構造を考える。インターフェースに対するテストなどPrivateメソッドなどの見えない部分はテストする必要があるか? Publicメソッド経由でPrivateメソッドはテストできる。だからPrivateメソッドのテストは各必要はない。

 

  • 以下、感じたことやその他のメモ。。

バージョン管理はやっぱり大事というか、最低限のもの。。コードを書く前にこれと仲良くならないといけない!!

パラメータライズドテスト これが凄いね。てすとにパラメータを与えることが出来る。。

Groovyのspockは凄い。

複数のパラメータで同じ内容を確かめたい時に使う(エラーケースを確認するなど)

 

破壊的なTest(関さん)

未知のものを探しに行く

テストを書く(通すためにする) OR テストをする(壊してやる、不具合を探す)

TDDは動くようにする、綺麗にするという繰り返しのループ。破壊的なテストをすることでコードを強くする事ができる

 

 

  • 振り返り

フレームワーク(KPT)http://ameblo.jp/tetsu7s/entry-10358337824.html

Keep

Try

Probrem