クラスとモジュール。
クラスはJAVAやC++で理解してるので問題なし。
モジュールははじめて知りましたが便利ですね。インスタンス化できないのがクラスと違う点。
4-1-2 インスタンスメソッド
str = 'abc' #破壊的でないメソッド p str.reverse() p str #破壊的なメソッド p str.reverse!()#strは更新される p str
4-1-4 クラスメソッド
class Ruler attr_accessor :length class << self #特異クラス def pair [new,new] end def trio [new,new,new] end end end p Ruler.pair p Ruler.trio
4-1-5 メソッドの呼び出し制限
class Processor def process protected_process = 3 end def protected_process private_process end protected :protected_process #メソッド定義の直後にアクセス権限 def private_process puts 'Done!' end private :private_process #メソッド定義の直後にアクセス権限 end processor = Processor.new p processor.process #->3
コメントでも書いてますがアクセス識別子をメソッド定義の直後に書くと。
4-1-6 クラスの継承
class Parent #スーパークラス def greet puts 'Hi!' end end class Child < Parent #サブクラス end p Child.superclass() #superclassを求めるメソッドか child = Child.new() child.greet() #Hi!
記述が楽でいいですね。メソッドのオーバーライドもできます。
4-1-8 特異メソッド
class Foo end foo = Foo.new() bar = Foo.new() def bar.singleton_method puts 'Called' end bar.singleton_method foo.singleton_method #in `<main>': undefined method `singleton_method' for #<Foo:0x00000002798fe0> (NoMethodError) #オブジェクト(bar)固有のメソッドを持つことができる #これを特異メソッドと呼ぶ
Fooクラスのオブジェクトfoo、barのうちbarにだけメソッドを定義できる。すげー。
4-1-9 クラス変数とそのスコープ
class Parent @@val = 'foo' #クラス変数。クラス定義内で定義 def self.say puts @@val end end class Child < Parent def say puts @@val end end Parent.say() Child.say() Child.new().say() #クラス変数はそのクラスとサブクラス以外からは参照できない child = Child.new() @@val='yeah' Parent.say #->yeah #warning: class variable access from toplevel
クラス変数、クラスが持つ変数。staticみたいなイメージでよいかいな。
スコープはそのクラスと継承したクラスからしか呼べないとのことだったけど
警告は出るものの呼べるし、書き換えもできてるね…良いのだろうか
4-1-11 ネストした定数の参照
VALUE = 'toplevel' class Foo VALUE = 'in foo class' def self.value p VALUE end end Foo.value() #->in foo class #まずはクラス定数、定義されてなければ上位のネストの変数を探す。
Fooクラス内のVALUE定義をしなければ結果はtoplevelになる、と。
4-2-1 モジュールの特徴
module Sweet def self.lot %w(brownie apple-pie bavarois pudding).sample #Array#sampleは要素をランダムに返す end end p Sweet.lot() p Sweet.lot()
モジュールは任意のメソッドを記述できるが、クラスと異なる点は
・インスタンスを生成できない
・継承することはできない
self.で定義すれば特異メソッド
そんなことよりsampleってメソッド良いなあ いちいち標準クラスメソッドに関心するw
4-2-2 メソッドをクラスのインスタンスメソッドとして取り込む
module Greetable def greet_to(name) puts "Hello, #{name}. My name is #{self.class}." end end class AliceClass include Greetable end alice = AliceClass.new() alice.greet_to('Bob') #->Hello, Bob. My name is AliceClass.
本命の使われ方なのかな?Greetableというモジュールをクラスでインクルードして使う。
クラス以外の部品化ってことですねー良いね
Mix-inというらしい。
4-2-3 メソッドをオブジェクトに取り込む
module Greetable def greet_to(name) puts "Hello,#{name}. I'm a #{self.class}." end end o = Object.new() o.extend Greetable #モジュールをオブジェクトの特異メソッドとして取り込む。extend。 o.greet_to 'World' #->Hello,World. I'm a Object. class Alice extend Greetable end Alice.greet_to('World') #->Hello,World. I'm a Class. #Aliceクラスではないのか
ここちょっと疑問で、.classってそのオブジェクトのクラスを返すメソッドで、
selfは自身なのでo.ObjectはObjectクラスであるのは良いんですが
AliceはAliceクラスじゃないのかなー
クラスクラスなのがよく分からない。
4-3-3 オブジェクトをコピーする
original = Object.new p original.object_id #->20333180 original.freeze #dupによるコピー copy_dup = original.dup p copy_dup.object_id #->20333080 p copy_dup.frozen? #->false #cloneによるコピー freezeされているかもコピー copy_clone = original.clone p copy_clone.object_id #->20332940 p copy_clone.frozen? #->true #配列のdupとcloneによるコピー value = 'foo' array = [value] array_dup = array.dup array_clone = array.clone #全て同じオブジェクト p value.object_id #->20332800 p array_dup[0].object_id #->20332800 p array_clone[0].object_id #->20332800 #なんで???
object_idが上の例と下の例で結果が異なる理由がさっぱり分かりません…