rubyとactive support for expert 2

15
Ruby & ActiveSupport for expart 藤岡岳之(xibbar) Vol.2

Upload: xibbar

Post on 19-Jan-2015

1.189 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: RubyとActive Support for expert 2

Ruby & ActiveSupportfor expart藤岡岳之(xibbar)

Vol.2

Page 2: RubyとActive Support for expert 2

このセッションって

xibbarこと藤岡が自分の勉強がてら気づいたことを発表するマニアックなセッションですrubyを詳しくというよりは、Railsのソースを読んでびっくりしたことから派生して、rubyとrailsの仕組みを調べた結果です

Page 3: RubyとActive Support for expert 2

今日の内容

1.mix-inをもっと深く2.define_xxxを集めてみたよ3.xxx_evalを集めてみたよ

Page 4: RubyとActive Support for expert 2

class methodを定義

# class methodを追加したい

class SampleClass def self.puts_str(str="hello") puts str endend

SampleClass.puts_str

解説ポイント•クラスメソッドとはクラスで共有のメソッド。

Page 5: RubyとActive Support for expert 2

mix-inでがんばる

# mix-inでクラスメソッドを追加したい

module SampleModule def self.puts_str(str="hello") puts str endendclass SampleClass include SampleModuleend

SampleClass.puts_str

解説ポイント•ぎゃ!•これでできないのかー。。。•できそうなんだけどなぁ。。

•結論としては、moduleメソッドはSampleModule.puts_strみたいにしか使えない。

% ruby ruby-expert2-2.rbruby-expert2-2.rb:12: undefined method `puts_str' for SampleClass:Class (NoMethodError)

Page 6: RubyとActive Support for expert 2

mix-inをもうちょっと

# なんとかmix-inでクラスメソッドを追加したい

module SampleModule def self.included(base) base.extend(ClassMethods) end module ClassMethods def puts_str(str="hello") puts str end endendclass SampleClass include SampleModuleend

SampleClass.puts_str

解説ポイント•なんだこれ?•クラスメソッドを書きたいだけなのに、なげーよ。

•でも、思いついた人はエラい!•includedってなんだ?•extendってなんだ?•上の2つは次で解説

Page 7: RubyとActive Support for expert 2

includedとextend

解説ポイント•なんと、includedの引数は呼び出し元そのもの

•extendは引数のモジュールを特異メソッドとして追加

included(class_or_module)

self が include されたときに対象のクラスまたはモジュールを引数にインタプリタから呼び出されます。

module Foo def self.included(mod) p "#{mod} include #{self}" end end class Bar include Foo end # => "Bar include Foo"

extend(module)

引数で指定したモジュールのインスタンスメソッドを self の特異メソッドとして追加します。self を返します。

include は、クラス(のインスタンス)に機能を追加しますが、extend は、ある特定のオブジェクトだけにモジュールの機能を追加したいときに使用します。

module Foo def a 'ok' endend

obj = Object.newobj.extend Foop obj.a #=> "ok"

Page 8: RubyとActive Support for expert 2

mix-inでできた

# なんとかmix-inでクラスメソッドを追加したい

module SampleModule def self.included(base) base.extend(ClassMethods) end module ClassMethods def puts_str(str="hello") puts str end endendclass SampleClass include SampleModuleend

SampleClass.puts_str

解説ポイント•includedされたタイミングで呼び出し元にClassMedhodsを特異メソッドとして追加

•以上の結果により、特異メソッドがクラスメソッドのように振る舞う

Page 9: RubyとActive Support for expert 2

楽な方法 orzmodule ClassMethods def puts_str(str="hello") puts str endendclass SampleClassend

SampleClass.extend ClassMethodsSampleClass.puts_str

解説ポイント•なんだ、クラスメソッドとしてextend

するだけでよかったのか。•これでincludeをクラスメソッドとしてやってみるとどうなる?

% ruby ruby-expert2-4.rbhello

Page 10: RubyとActive Support for expert 2

includeするとどうなるmodule ClassMethods def puts_str(str="hello") puts str endendclass SampleClassend

SampleClass.include ClassMethodsSampleClass.puts_str

解説ポイント•特異メソッドに対する追加はできるけど、全体に対する追加はできない。

•privateなんだとさ。•結論として、extendで特異メソッドの追加はできるが、includeでクラスメソッドの追加をする時は工夫が必要になる。

•こんなところに結論書くなってか。•extendもmix-inの一つだよな。。。

includeしかmix-inと呼ばないなんてことはないよな。。。

% ruby ruby-expert2-5.rbruby-expert2-5.rb:11: private method `include' called for SampleClass:Class (NoMethodError)

Page 11: RubyとActive Support for expert 2

とりあえずまとめ

extendでclass methodの追加はできるincludeでclass methodの追加はできないextendで拡張するのもmix-inだ(ろう)

Page 12: RubyとActive Support for expert 2

define_xxxを集めてみた

define_method(Moduleクラス)

これ以外にdefine_xxxはなかったorz

Page 13: RubyとActive Support for expert 2

気を取り直して使ってみる

class SampleClass define_method(:puts_str){¦str¦ puts str }end

sample=SampleClass.newsample.puts_str("hello")

解説ポイント•まあ無理して使わなくてもいいな•ただ、動的にメソッドを定義できる

•それがカッコいい•inplace editorの受ける部分の定義

% ruby ruby-expert2-6.rbhello

Page 14: RubyとActive Support for expert 2

eval兄弟を集めてみた

instance_eval(Objectクラス)class_eval(Moduleクラス)module_eval(Moduleクラス)eval(組み込み関数)

Page 15: RubyとActive Support for expert 2

おしまい

おしまい次回以降予定ブロック、クロージャ、イテレータlambda、proc、ついでにbinding継続method_missingerbなんてどう?