Meta programing ruby monday

58
メタプログラミング Ruby~ 月曜日 ~ The_haigo 121113日火曜日

description

LT_Chukyo 4回目

Transcript of Meta programing ruby monday

Page 1: Meta programing ruby monday

メタプログラミングRuby~月曜日~

The_haigo

12年11月13日火曜日

Page 2: Meta programing ruby monday

こんにちは

12年11月13日火曜日

Page 3: Meta programing ruby monday

the_haigoです

12年11月13日火曜日

Page 4: Meta programing ruby monday

わたくし実は

12年11月13日火曜日

Page 5: Meta programing ruby monday

リア充な草食系男子

12年11月13日火曜日

Page 6: Meta programing ruby monday

じゃなかった

12年11月13日火曜日

Page 7: Meta programing ruby monday

リア住な僧職系男子なので

12年11月13日火曜日

Page 8: Meta programing ruby monday

今回は仏の教え

12年11月13日火曜日

Page 9: Meta programing ruby monday

ではなく

12年11月13日火曜日

Page 10: Meta programing ruby monday

Matzの教えを布教するため

12年11月13日火曜日

Page 11: Meta programing ruby monday

LT(LongTalk)を行います

メタプログラミングRubyの

12年11月13日火曜日

Page 12: Meta programing ruby monday

今回は

第1章 月曜日:オブジェクトモデル

12年11月13日火曜日

Page 13: Meta programing ruby monday

何度も言いますが

12年11月13日火曜日

Page 14: Meta programing ruby monday

メタプログラミングとは魔法のようなものであり

12年11月13日火曜日

Page 15: Meta programing ruby monday

使い方を誤ると

12年11月13日火曜日

Page 16: Meta programing ruby monday

最悪死にます

12年11月13日火曜日

Page 17: Meta programing ruby monday

では初めていきます

12年11月13日火曜日

Page 18: Meta programing ruby monday

本の流れ主に5つの章に別れており

1章 月曜日~5章 金曜日でメタプログラミングを実例を交えながら説明していく

物語調で書かれており、「レガシーシステムをハンマーでぶっ叩いて直すやつら」

という名古屋の怖い人達のような上司ビルと学んでいく感じです

12年11月13日火曜日

Page 19: Meta programing ruby monday

1.2オープンクラス

流れ

Bookwormのソースコードに目を通し

リファクタリングを行う

アルファベットとスペースを残して特殊文字列を削除する機能が付いている

12年11月13日火曜日

Page 20: Meta programing ruby monday

1.2 オープンクラス

def to_alphanumeric() s.gsub /[^\w\a]/,””end

require ‘test/unit’class ToAlphanumericTess < Test::Unit::TestCase def test_strips_non_alpanumeric_characters assert_equal ‘3 the Magic Number’, to_alphanumeric(‘#3, the *Magic, Number*?’) endend

12年11月13日火曜日

Page 21: Meta programing ruby monday

このメソッドはオブジェクト指向じゃないね

外部のメソッドに文字列を渡すんじゃなくて、文字列自身に変換してもらった方がいいんじゃないかな?

ビルさん

12年11月13日火曜日

Page 22: Meta programing ruby monday

でもこれって、標準のStringクラスじゃないですか、メソッド追加するなら、新しくAlphaNumericStringクラス作ったほうがいいっすよ。でも、そこまでする必要はないかもしれないっすね

別にStingクラス拡張すればいいじゃん

12年11月13日火曜日

Page 23: Meta programing ruby monday

class String def to_alphanumeric gsub /[^\w\s]/,’’ endend

class StringExtensionsTest < Test::Unit::TestCase def test_strips_non_alphanumeric_characters assert_equal ‘3 the Magic Number’, ‘#3, the *Magic, Number*?’.to_alphanumeric endend

12年11月13日火曜日

Page 24: Meta programing ruby monday

Bookworm の関数to_alphanumeric

オブジェクトモデルは「このメソッドはどのクラスのものなのか?」というのがわかるようにするべきString class

def to_alphanumeric

ではなく

12年11月13日火曜日

Page 25: Meta programing ruby monday

1.2.1 クラス定義の中身

3.times do class C puts “Hello” endend

クラスを定義するコードとその他のコードの違いはない

実行HelloHelloHello

これは同じクラスを3回定義したわけではない

12年11月13日火曜日

Page 26: Meta programing ruby monday

class D def x; ‘x’;endend

class D def y; ’y’; endend

obj = D.newobj.x #=> ‘x’obj.y #=> ‘y’

class Dを書いた時はまだ、クラスは存在していない。Rubyがクラス定義の中に入った時に、初めて定義をする1回目ではxメソッドを定義して2回目の際は既にクラスがあるので、class Dを再オープンしてyメソッドを追加する。

12年11月13日火曜日

Page 27: Meta programing ruby monday

・Rubyのclassキーワードは、クラス宣言と言うよりも、スコープ演算子のようなものである。・もちろん、存在しないクラスは作成するがそれは副作用でしかない・classの主な仕事は、あなたをクラスのコンテキストにつれていくことである。

12年11月13日火曜日

Page 28: Meta programing ruby monday

既存のクラスを再オープンして、いつでもそれを修正できる

それがオープンクラスだ!(ドヤッ

12年11月13日火曜日

Page 29: Meta programing ruby monday

1.2.2オープンクラスの問題点def replace(array, from ,to) array.each_with_index do |e,i| array[i] = to if e == from endend

def test_replace book_topics = [‘html’,‘java’,‘css’] replace(book_topics,‘java’,‘ruby’) expected = [‘html’,‘ruby’,‘css’] assert_equal expected , book_topicsend

12年11月13日火曜日

Page 30: Meta programing ruby monday

class Array def replace(from,to) each_with_index do |e,i| self[i] = to if e == from end endend

def test_replace book_topics = [‘html’,‘java’,‘css’] replace(book_topics,‘java’,‘ruby’) expected = [‘html’,‘ruby’,‘css’] assert_equal expected , book_topicsend

12年11月13日火曜日

Page 31: Meta programing ruby monday

バカめ!成功するとでも思ったか!

12年11月13日火曜日

Page 32: Meta programing ruby monday

1.2.3 猿マネとモンキーパッチArray.new().methods.grep = /^re/ #=> [:replace,:reject]

つまりArrayに組み込まれている Replaceメソッドを上書きして

しまったので、テストコードが失敗したということである

名前衝突がないように気をつけよう!

12年11月13日火曜日

Page 33: Meta programing ruby monday

1.3クラスの真実

class MyClass def my_method @v = 1 endend

obj = MyClass.newobj.class #=> MyClass

12年11月13日火曜日

Page 34: Meta programing ruby monday

インスタンス変数obj.instance_variables #=> []obj.my_methodobj.instance_variables #=> [:@v]

・Rubyではオブジェクトのインスタンス変数はクラスとも何のつながりもない・インスタンス変数は値を代入した時に初めて出現する・同じオブジェクトであってもインスタンス変数の数が異なることがある

12年11月13日火曜日

Page 35: Meta programing ruby monday

メソッド

MyClass  my_method()

obj    @var = 1

classオブジェクト

インスタンス変数 メソッド

クラス

・オブジェクトの内部には、インスタンス変数とクラスへの参照があるだけ・クラスにはメソッドがある・クラスを共有しているオブジェクトはメソッドも共有している

12年11月13日火曜日

Page 36: Meta programing ruby monday

メソッド・objがmy_method()メソッドを持っているというが・MyClassがmy_method()メソッドを持っているとは言わない後者だとMyClassがクラスメソッドとしてmy_method()があると勘違いしてしまう

my_method()をメソッドではなくMyClassのインスタンスメソッドと呼ぶようにすればよい

・オブジェクトに着目している時はメソッド・クラスに着目している時はインスタンスメソッド

12年11月13日火曜日

Page 37: Meta programing ruby monday

こんすとらくたーclass MyClass def initialize(hoge,huga) @hoge = hoge @huga = huga end attr_accesser :hoge,:hugaend

obj = MyClass.new(“りゅか”,”にゃん”)

obj.instance_variables #=>[:@hoge,:@huga]puts obj.hoge + obj.huga #=> “りゅかにゃん”

12年11月13日火曜日

Page 38: Meta programing ruby monday

なにやってるか(妄想)

class MyClass << Class def MyClass.new() initialize(*arg) end def initialize() #何もしない endend

12年11月13日火曜日

Page 39: Meta programing ruby monday

オープンクラス!12年11月13日火曜日

Page 40: Meta programing ruby monday

class MyClass def initialize(hoge,huga) @hoge = hoge @huga = huga end attr_accesser :hoge,:hugaend

という風にnew()する時に実行されるinitialize()を再定義してインスタンス変数を

定義していくんですねー

12年11月13日火曜日

Page 41: Meta programing ruby monday

1.3.2 クラス再訪

クラスはオブジェクトである

12年11月13日火曜日

Page 42: Meta programing ruby monday

・Classクラス及びすべてのクラスはObjectクラスを継承している(Classクラスは厳密にはModuleクラスだが)

・Objectに当てはまるものはClassにも当てはまる

String.superclass #=> ObjectClass.class #=> ClassClass.superclass #=> ModuleClass.instance_methods(false) #=> [:superclass,:allocate,:new]

12年11月13日火曜日

Page 43: Meta programing ruby monday

class

obj1

obj2

MyClass

Object

Classnew()

...

Module

class

class class

superclass superclass

・オブジェクトと同じように、クラスも参照を使って保持する・obj1とMyClassはどちらも参照であり違うのは ・obj1は変数 ・MyClassは定数である

12年11月13日火曜日

Page 44: Meta programing ruby monday

クラスはオブジェクトで、クラス名は定数なのである

12年11月13日火曜日

Page 45: Meta programing ruby monday

1.3.3 定数・大文字で始まる参照は、クラス名やモジュール名も含めて全て定数である・定数のスコープには、変数のスコープと異なるルールがある

module MyModule MyConstant = ‘外部の定数’

class MyClass MyConstant = ‘内部の定数’

endend 定数はファイルシステムみたいに

ツリー状である12年11月13日火曜日

Page 46: Meta programing ruby monday

1.3.4 オブジェクトとクラスまとめ

   オブジェクトとは何か?

インスタンス変数の集まりにクラスへのリンクが付いたものである

オブジェクトのメソッドは、オブジェクトではなくオブジェクトのクラスに住んでいて、クラスのインスタンスメソッドとも呼ばれる

12年11月13日火曜日

Page 47: Meta programing ruby monday

まとめ2    クラスとは何か? 

オブジェクト(Classクラスのインスタンス)に

・インスタンスメソッドの一覧

・スーパークラスへのリンクがついたものである

ClassはModuleのサブクラスであり、クラスもモジュールである

12年11月13日火曜日

Page 48: Meta programing ruby monday

まとめ3

通常のオブジェクトと同じようにクラスもnew()などのメソッドを持っている

これらのメソッドはClassのインスタンスメソッドである。

また、クラスにはクラス名という参照を使ってアクセスしなければならない

12年11月13日火曜日

Page 49: Meta programing ruby monday

1.4 クイズ引かれていない線

Objectのクラスは?

Moduleのスーパークラスは?

Classのクラスは?

instance_variable_se(“@x”,10)して新しく作ったらどんな感じになる?

12年11月13日火曜日

Page 50: Meta programing ruby monday

1.4 クイズ引かれていない線

obj1

obj2

MyClass

Object

Classnew()

...

Moduleclass

class

class

superclass superclass

superclass

class

class

obj3@x=10 class

12年11月13日火曜日

Page 51: Meta programing ruby monday

1.5メソッドを呼び出す時に何が起きているの?

Rubyはメソッドを呼び出すと以下のことを行う

1メソッドを探す,これをメソッド探索という

2メソッドを実行する,これにはselfと呼ばれるものが必要だ

12年11月13日火曜日

Page 52: Meta programing ruby monday

心折れたので省略

obj.my_method() obj

classMySubclass

MyClassmy_method()

Object発見

12年11月13日火曜日

Page 53: Meta programing ruby monday

せるふ

JSとかのthisとかそんなもん 省略したり、明示的にメソッド定義できたりします

カレントオブジェクトっていうんだって!

クラス定義の中ならクラスがCObj

関数定義ならインスタンス変数がCObj

12年11月13日火曜日

Page 54: Meta programing ruby monday

class Array def replace(from,to) each_with_index do |e,i| self[i] = to if e == from end endend

12年11月13日火曜日

Page 55: Meta programing ruby monday

1.7オブジェクトモデルまとめ

オブジェクトは複数のインスタンス変数とクラスへのリンクで構成されている

オブジェクトのメソッドはオブジェクトのクラスに住んでいる(クラスから見れば、それはインスタンスメソッドと呼ばれる)

クラスはClassクラスのオブジェクトである。クラス名は単なる定数である

12年11月13日火曜日

Page 56: Meta programing ruby monday

ClassはModuleのサブクラスである。モジュールはメソッドを集めたものである。クラスはnew()出インスタンス化したり、superclass()で階層構造を作ったりできる。

定数はファイルシステムのようにツリー上に配置されている。モジュールやクラスの名前がディレクトリ、通常の定数がファイルのようになっている

12年11月13日火曜日

Page 57: Meta programing ruby monday

クラスはそれぞれBasicObjectまで続く継承チェーンを持っている

メソッドを呼び出すと、Ruby はレシーバのクラスに向かって一歩右に進み、それから継承チェーンを上へ向かって進んでいく。メソッドを発見するか継承チェーンが終わるまでそれは続く。

クラスがモジュールをインクルードすると、そのクラスの真上の継承チェーンにモジュールが挿入される

12年11月13日火曜日

Page 58: Meta programing ruby monday

メソッドを呼び出す時、レシーバがselfになる。

モジュール(あるいはクラス)を定義する時、モジュールがselfになる

インスタンス変数は常にselfのインスタンス変数とみなされる

レシーバを明示的に支持せずにメソッドを呼び出すと、selfのメソッドだとみなされる

12年11月13日火曜日