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されていると勝手に分岐してしまうので、もうちょっといい書き方がある気がする。
Solved in Perl6 : Jonathan Worthington
今回個人的に一番面白かった。Jonathanの英語もわかりやすかったし、Perl6を試してみる気にもなった。
バッテリーが落ちてしまってノートにメモってたので、後でまとめよう。。
CPAN Paclager (dann)
- 依存モジュール解決して、RPM,dpkg作るモジュール
- 既存のCPANPLUS::Distだと依存関係の解決,エラー訂正が不十分
- 再起的に依存解決します。
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
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
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を持ったモジュールのどのへんがいいのかってことを解説する感じだった。