rubyとactive support for expert 2
DESCRIPTION
TRANSCRIPT
![Page 1: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/1.jpg)
Ruby & ActiveSupportfor expart藤岡岳之(xibbar)
Vol.2
![Page 2: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/2.jpg)
このセッションって
xibbarこと藤岡が自分の勉強がてら気づいたことを発表するマニアックなセッションですrubyを詳しくというよりは、Railsのソースを読んでびっくりしたことから派生して、rubyとrailsの仕組みを調べた結果です
![Page 3: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/3.jpg)
今日の内容
1.mix-inをもっと深く2.define_xxxを集めてみたよ3.xxx_evalを集めてみたよ
![Page 4: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/4.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/5.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/6.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/7.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/8.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/9.jpg)
楽な方法 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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/10.jpg)
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/11.jpg)
とりあえずまとめ
extendでclass methodの追加はできるincludeでclass methodの追加はできないextendで拡張するのもmix-inだ(ろう)
![Page 12: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/12.jpg)
define_xxxを集めてみた
define_method(Moduleクラス)
これ以外にdefine_xxxはなかったorz
![Page 13: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/13.jpg)
気を取り直して使ってみる
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](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/14.jpg)
eval兄弟を集めてみた
instance_eval(Objectクラス)class_eval(Moduleクラス)module_eval(Moduleクラス)eval(組み込み関数)
![Page 15: RubyとActive Support for expert 2](https://reader033.vdocuments.mx/reader033/viewer/2022051818/54bd19164a7959766e8b45ae/html5/thumbnails/15.jpg)
おしまい
おしまい次回以降予定ブロック、クロージャ、イテレータlambda、proc、ついでにbinding継続method_missingerbなんてどう?