Ruby Gold勉強メモ3

f:id:ihatov08:20170313091034j:plain

protectedとprivate

# protected以降で定義されたメソッドは、そのクラスとサブクラスのインスタンスから
# 呼び出すことができる。
class Foo
def bar(obj=nil) # !> previous definition of bar was here
foo # ok
self.foo # ok
obj.foo # ok
end
protected
def foo # !> previous definition of foo was here
p 'foo'
end
end
Foo.new.bar(Foo.new)            # => "foo"
# privateはレシーバを指定することはできない
class Foo
def bar(obj=nil) # !> method redefined; discarding old bar
foo # ok
self.foo # bad
obj.foo # bad
end
private
def foo # !> method redefined; discarding old foo
p 'foo'
end
end
Foo.new.bar(Foo.new)            # => 
# ~> -:19:in `bar': private method `foo' called for #<Foo:0x007f8bcc04cea0> (NoMethodError)

module内定数

module M
def foo
p CONST
end
end
class Hoge
CONST = 'foo'
include M
end
# module MのCONSTを見に行ってしまう
Hoge.new.foo                     # => 
# ~> -:11:in `foo': uninitialized constant M::CONST (NameError)
# ~>    from -:20:in `<main>'
# >> "foo"
# エラーが起きないようにするには、以下のようにする必要がある
module M
def foo
p Hoge::CONST
end
end

undef_methodとremove_methodの違い

  • undef_methodはスーパークラスに同名のメソッドが存在しても、nomethod errorが発生する
  • remove_methodの場合は、スーパークラスに同名のメソッドが存在すると、スーパークラスのメソッドが呼ばれる
class Foo
def foo
p 'foo'
end
end
class Bar < Foo
def foo
p 'bar'
end
end
class Bar
remove_method :foo
end
Foo.new.foo
Bar.new.foo                     # => "foo"
class Hoge
def hoge
p 'hoge'
end
end
class Piyo < Hoge
def hoge
p 'hoge'
end
end
class Piyo
undef_method :hoge
end
Hoge.new.hoge                   # => "hoge"
Piyo.new.hoge                   # => 
# ~> -:36:in `<main>': undefined method `hoge' for #<Piyo:0x007fa105046818> (NoMethodError)
class Foo
def foo
'foo'
end
end
class Bar < Foo
def foo
super + 'bar'
end
alias bar foo
# undef fooしてもスーパークラスのメソッドには影響なし
undef foo
end
Bar.new.bar                     # => "foobar"
class Piyo
def piyo
'piyo'
end
end
class Hoge < Piyo
# メソッド定義してからじゃないと、aliasはできない
alias hoge piyo
def piyo
super + 'hoge'
end
undef piyo
end
Hoge.new.piyo                   # => 
# ~> -:32:in `<main>': undefined method `piyo' for #<Hoge:0x007f991604c750> (NoMethodError)

pメソッドと、putsメソッドのオーバライド

  • pはinspect
  • putsはto_s
  • それぞれでオーバライドできる
class Person
def initialize(name)
@name = name
end
def inspect
"My name is #{@name}"
end
def to_s
"to_s method override #{@name}"
end
end
p Person.new('taro')              # => My name is taro
puts Person.new('hanako')       # => nil
# >> My name is taro
# >> to_s method override hanako

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です