Meta programing ruby monday
-
Upload
yuisho-takafuji -
Category
Technology
-
view
489 -
download
0
description
Transcript of Meta programing ruby monday
メタプログラミングRuby~月曜日~
The_haigo
12年11月13日火曜日
こんにちは
12年11月13日火曜日
the_haigoです
12年11月13日火曜日
わたくし実は
12年11月13日火曜日
リア充な草食系男子
12年11月13日火曜日
じゃなかった
12年11月13日火曜日
リア住な僧職系男子なので
12年11月13日火曜日
今回は仏の教え
12年11月13日火曜日
ではなく
12年11月13日火曜日
Matzの教えを布教するため
12年11月13日火曜日
LT(LongTalk)を行います
メタプログラミングRubyの
12年11月13日火曜日
今回は
第1章 月曜日:オブジェクトモデル
12年11月13日火曜日
何度も言いますが
12年11月13日火曜日
メタプログラミングとは魔法のようなものであり
12年11月13日火曜日
使い方を誤ると
12年11月13日火曜日
最悪死にます
12年11月13日火曜日
では初めていきます
12年11月13日火曜日
本の流れ主に5つの章に別れており
1章 月曜日~5章 金曜日でメタプログラミングを実例を交えながら説明していく
物語調で書かれており、「レガシーシステムをハンマーでぶっ叩いて直すやつら」
という名古屋の怖い人達のような上司ビルと学んでいく感じです
12年11月13日火曜日
1.2オープンクラス
流れ
Bookwormのソースコードに目を通し
リファクタリングを行う
アルファベットとスペースを残して特殊文字列を削除する機能が付いている
12年11月13日火曜日
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日火曜日
このメソッドはオブジェクト指向じゃないね
外部のメソッドに文字列を渡すんじゃなくて、文字列自身に変換してもらった方がいいんじゃないかな?
ビルさん
12年11月13日火曜日
でもこれって、標準のStringクラスじゃないですか、メソッド追加するなら、新しくAlphaNumericStringクラス作ったほうがいいっすよ。でも、そこまでする必要はないかもしれないっすね
別にStingクラス拡張すればいいじゃん
12年11月13日火曜日
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日火曜日
Bookworm の関数to_alphanumeric
オブジェクトモデルは「このメソッドはどのクラスのものなのか?」というのがわかるようにするべきString class
def to_alphanumeric
ではなく
12年11月13日火曜日
1.2.1 クラス定義の中身
3.times do class C puts “Hello” endend
クラスを定義するコードとその他のコードの違いはない
実行HelloHelloHello
これは同じクラスを3回定義したわけではない
12年11月13日火曜日
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日火曜日
・Rubyのclassキーワードは、クラス宣言と言うよりも、スコープ演算子のようなものである。・もちろん、存在しないクラスは作成するがそれは副作用でしかない・classの主な仕事は、あなたをクラスのコンテキストにつれていくことである。
12年11月13日火曜日
既存のクラスを再オープンして、いつでもそれを修正できる
それがオープンクラスだ!(ドヤッ
12年11月13日火曜日
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日火曜日
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日火曜日
バカめ!成功するとでも思ったか!
12年11月13日火曜日
1.2.3 猿マネとモンキーパッチArray.new().methods.grep = /^re/ #=> [:replace,:reject]
つまりArrayに組み込まれている Replaceメソッドを上書きして
しまったので、テストコードが失敗したということである
名前衝突がないように気をつけよう!
12年11月13日火曜日
1.3クラスの真実
class MyClass def my_method @v = 1 endend
obj = MyClass.newobj.class #=> MyClass
12年11月13日火曜日
インスタンス変数obj.instance_variables #=> []obj.my_methodobj.instance_variables #=> [:@v]
・Rubyではオブジェクトのインスタンス変数はクラスとも何のつながりもない・インスタンス変数は値を代入した時に初めて出現する・同じオブジェクトであってもインスタンス変数の数が異なることがある
12年11月13日火曜日
メソッド
MyClass my_method()
obj @var = 1
classオブジェクト
インスタンス変数 メソッド
クラス
・オブジェクトの内部には、インスタンス変数とクラスへの参照があるだけ・クラスにはメソッドがある・クラスを共有しているオブジェクトはメソッドも共有している
12年11月13日火曜日
メソッド・objがmy_method()メソッドを持っているというが・MyClassがmy_method()メソッドを持っているとは言わない後者だとMyClassがクラスメソッドとしてmy_method()があると勘違いしてしまう
my_method()をメソッドではなくMyClassのインスタンスメソッドと呼ぶようにすればよい
・オブジェクトに着目している時はメソッド・クラスに着目している時はインスタンスメソッド
12年11月13日火曜日
こんすとらくたー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日火曜日
なにやってるか(妄想)
class MyClass << Class def MyClass.new() initialize(*arg) end def initialize() #何もしない endend
12年11月13日火曜日
オープンクラス!12年11月13日火曜日
class MyClass def initialize(hoge,huga) @hoge = hoge @huga = huga end attr_accesser :hoge,:hugaend
という風にnew()する時に実行されるinitialize()を再定義してインスタンス変数を
定義していくんですねー
12年11月13日火曜日
1.3.2 クラス再訪
クラスはオブジェクトである
12年11月13日火曜日
・Classクラス及びすべてのクラスはObjectクラスを継承している(Classクラスは厳密にはModuleクラスだが)
・Objectに当てはまるものはClassにも当てはまる
String.superclass #=> ObjectClass.class #=> ClassClass.superclass #=> ModuleClass.instance_methods(false) #=> [:superclass,:allocate,:new]
12年11月13日火曜日
class
obj1
obj2
MyClass
Object
Classnew()
...
Module
class
class class
superclass superclass
・オブジェクトと同じように、クラスも参照を使って保持する・obj1とMyClassはどちらも参照であり違うのは ・obj1は変数 ・MyClassは定数である
12年11月13日火曜日
クラスはオブジェクトで、クラス名は定数なのである
12年11月13日火曜日
1.3.3 定数・大文字で始まる参照は、クラス名やモジュール名も含めて全て定数である・定数のスコープには、変数のスコープと異なるルールがある
module MyModule MyConstant = ‘外部の定数’
class MyClass MyConstant = ‘内部の定数’
endend 定数はファイルシステムみたいに
ツリー状である12年11月13日火曜日
1.3.4 オブジェクトとクラスまとめ
オブジェクトとは何か?
インスタンス変数の集まりにクラスへのリンクが付いたものである
オブジェクトのメソッドは、オブジェクトではなくオブジェクトのクラスに住んでいて、クラスのインスタンスメソッドとも呼ばれる
12年11月13日火曜日
まとめ2 クラスとは何か?
オブジェクト(Classクラスのインスタンス)に
・インスタンスメソッドの一覧
・スーパークラスへのリンクがついたものである
ClassはModuleのサブクラスであり、クラスもモジュールである
12年11月13日火曜日
まとめ3
通常のオブジェクトと同じようにクラスもnew()などのメソッドを持っている
これらのメソッドはClassのインスタンスメソッドである。
また、クラスにはクラス名という参照を使ってアクセスしなければならない
12年11月13日火曜日
1.4 クイズ引かれていない線
Objectのクラスは?
Moduleのスーパークラスは?
Classのクラスは?
instance_variable_se(“@x”,10)して新しく作ったらどんな感じになる?
12年11月13日火曜日
1.4 クイズ引かれていない線
obj1
obj2
MyClass
Object
Classnew()
...
Moduleclass
class
class
superclass superclass
superclass
class
class
obj3@x=10 class
12年11月13日火曜日
1.5メソッドを呼び出す時に何が起きているの?
Rubyはメソッドを呼び出すと以下のことを行う
1メソッドを探す,これをメソッド探索という
2メソッドを実行する,これにはselfと呼ばれるものが必要だ
12年11月13日火曜日
心折れたので省略
obj.my_method() obj
classMySubclass
MyClassmy_method()
Object発見
12年11月13日火曜日
せるふ
JSとかのthisとかそんなもん 省略したり、明示的にメソッド定義できたりします
カレントオブジェクトっていうんだって!
クラス定義の中ならクラスがCObj
関数定義ならインスタンス変数がCObj
12年11月13日火曜日
class Array def replace(from,to) each_with_index do |e,i| self[i] = to if e == from end endend
12年11月13日火曜日
1.7オブジェクトモデルまとめ
オブジェクトは複数のインスタンス変数とクラスへのリンクで構成されている
オブジェクトのメソッドはオブジェクトのクラスに住んでいる(クラスから見れば、それはインスタンスメソッドと呼ばれる)
クラスはClassクラスのオブジェクトである。クラス名は単なる定数である
12年11月13日火曜日
ClassはModuleのサブクラスである。モジュールはメソッドを集めたものである。クラスはnew()出インスタンス化したり、superclass()で階層構造を作ったりできる。
定数はファイルシステムのようにツリー上に配置されている。モジュールやクラスの名前がディレクトリ、通常の定数がファイルのようになっている
12年11月13日火曜日
クラスはそれぞれBasicObjectまで続く継承チェーンを持っている
メソッドを呼び出すと、Ruby はレシーバのクラスに向かって一歩右に進み、それから継承チェーンを上へ向かって進んでいく。メソッドを発見するか継承チェーンが終わるまでそれは続く。
クラスがモジュールをインクルードすると、そのクラスの真上の継承チェーンにモジュールが挿入される
12年11月13日火曜日
メソッドを呼び出す時、レシーバがselfになる。
モジュール(あるいはクラス)を定義する時、モジュールがselfになる
インスタンス変数は常にselfのインスタンス変数とみなされる
レシーバを明示的に支持せずにメソッドを呼び出すと、selfのメソッドだとみなされる
12年11月13日火曜日