datamapperでassociationがあることを保証したい

class Post
  include DataMapper::Resource
  property :title
  property :body

  belongs_to :author
end

class Author
  include DataMapper::Resource
  property :name
  property :addr

  has n, :posts
end

若干おかしな例だけど、Author.allで取得する時にpostを持たないAuthorを入れないためにはdm-validationsを使えばいいみたい。

class Author
  include DataMapper::Resource
  property :name
  property :addr

  has n, :posts

  validates_present :posts
end

(追記)

dm-validationをrequireするとauto-validationが効くので、saveするときに注意しないといけない

if post.save 
  # success
else 
  # failed
  post.errors.each do |e|
    e.puts
  end
end

Sinatra+Erubisでcontent_forしようとしてはまった。

content_forはsinatraにないので、githubで公開されているGitHub - foca/sinatra-content-for: Sinatra extension to use a `content_for` helper similar to Rails' – Don't use it, use Sinatra::Contrib instead.を使おうと思っていたい目にあったのでメモ。

とりあえず動かしてみるとyield_content :hogeした場所にブロックの内容が入らないばかりかlayoutでyieldしている直後に入る。だいたい原因はわかったけどそもそもErbの場合はなんでちゃんと動くのか、とか疑問点は残ってるけど追う元気がないので解決だけ

まずErubis用に書いたrender_erubisを修正する。

# 修正前
def render_erubis(data, options,locals, &block) # Sinatra v0.10.1
   ::Erubis::Eruby.new(data, options).result(binding)
end

# 修正後
def render_erubis(data, options,locals, &block) # Sinatra v0.10.1
   options[:preamble]  = false
   options[:postamble] = false
   _buf = ""
   ::Erubis::Eruby.new(data, options).result(binding)
   _buf
end

Erubisはpreambleとpostambleを切っとかないと最初に_buf = ''ってつけて面倒だから切っておく。かわりに_bufは外で定義しておく。

それから、sinatra-content-forのyield_contentを以下のように変更する。

def yield_content(key, *args)
  content_blocks[key.to_sym].map do |content| 
    if respond_to?(:block_is_haml?) && block_is_haml?(content)
      capture_haml(*args, &content)
    elsif Erubis::VERSION # これでいいのかは微妙。
      content.binding.eval ' _buf = "" '
      content.call(*args)
    else
      content.call
    end
  end.join
end

contentにはcontent_for :hoge do ... endで書かれたブロックが入っていて、yield_contentで指定したキーに追加されたブロックを実行する。Erubisの場合、rubyに変換されてevalで実行されるコードは以下のようになっていて、content_forブロックをcallするとそれ以前に追加された_bufごと出力されてしまう。

_buf << '<h1>Hello World!</h1>';
 foo = 0 
 var = 10
_buf << '<div>  Foo + Var is ';
_buf << (foo + var).to_s;
_buf << '</div>';
content_for :styles do
_buf << '<!-- Content For Block Start -->';
_buf << '  ';
_buf << ( stylesheet_link_tag "stylesheets/style.css", :media => 'screen' ).to_s; 
_buf << '<!-- Content For Block Start -->';
end

なので、content.binding.evalでブロックの_bufをいったんクリアする。これでよくわからない現象は無くなったが、yield_contentを書く時に<%= %>と書かなければいけなくなってしまった。

あとErubisがrequireされていると勝手に分岐してしまうので、もうちょっといい書き方がある気がする。

Event programming fun with AnyEvent and Coro (miyagawa)

  • Event loop?
  • POE以外って?
  • Intro, Basic, Examples, Tips
  • DBI for event loops
  • Danga::Socket, Event::Lib -> inncompatible
  • 書き方が違い過ぎてこまる。POE::Componentのモジュール数250...
  • AnyEvent::Impl::* AnyEventで書いたコードはどれでも動く
  • バックエンドを自動で切り替えられる
  • PoCoを書くのはやめよう!
  • condvar, Timer, I/O, subprocess, modules

http://conferences.yapcasia.org/ya2009/talk/2218

Modern Catalyst - (hide)

  • M V C ::がdeprecatedになった
  • NEXTがdeprecated
  • mk_accessors -> has
  • ...とかとか
  • use Moose; extends Catalyst ...
  • Catalyst::Pluginは基本的に使わない. 怒られます
  • Helper Method, method modifierでごにょごにょ
  • Roleに切り分ける -> setupに突っ込める
  • BEGIN phaseでCatalyst::Controllerをextendする
  • Controllerの拡張 -> Moose::Role + MooseX::MethodAttributes
  • ActionClass
    • Catalyst::Actionの拡張
    • ActionClass2つは使えない
  • 最近はActionRole
  • Dispatcher
    • default :Private -> 使えなくなる
    • default :Path
    • index :Path :Args(0) -> index :Private
    • Chained
    • $c->go : 行き先のautoとかも全部実行
    • $c->visit : 行き先のautoとかも実行していきっぱなし
  • Controllerを小さくしてmodelを賢くしなさい
  • Model::Adaptor
  • Test
  • Catalyst::Delta, Catalyst::Upgradingに書いてあるよ
  • PSGI -> WSGI/Perl

http://blog.hide-k.net/archives/2009/09/yapcasia_2009mo.php

API Design - Shawn Moore (sartak)

  • Path::Dispatcher, Dist::Zilla, IM:Engine
  • all these modules are moose based
  • the secret of APIs
  • So Many test. please
  • why?
  • testを書けばAPIが堪え難いかどうかわかる
  • Class::MOP
  • traits -> ロール指定
  • シュガー層の分離
  • Dist::Zilla

plagin based
多分MIからIを抜いたもの?
CPAN::RT

  • IM::Engine -> Instant MessagingのFramework
  • Role == Trait? trait from small talk.
  • 結論 : テストかけ

とりあえずテスト書けってことはわかった。APIデザインの一般的な話しというよりは、良いAPIを持ったモジュールのどのへんがいいのかってことを解説する感じだった。

http://sartak.org/talks/yapc-asia-2009/api-design/