地方でリモートワーク

プログラミング、先物、fx,仮想通貨なんでもやります

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