気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

Ruby Gold対策(オブジェクト指向、標準添付ライブラリ)

Ruby公式資格教科書の基礎力確認問題で学習した事項を以下に記載する。

定数

・クラスに定義した定数にメソッド内からアクセス可能

class C
  A = 1
  def method
    puts A
  end
end
C.new.method # => 1

メソッド内に定数を定義できない
(メソッド複数回実行が前提のため、初期化を許可しない)

class C
  def method
    A = 1  # => SyntaxError: (irb):10: dynamic constant assignment
  end
end

・ネストした定数のスコープ

module M
  A = 1
  class B
    # SyntaxErrorにならない。モジュールとクラスでは別の定数となる
    A = 2
  end
end

class C
  A = 1
  class B
    # これも問題なし。
    A = 2
  end
end

定数はモジュールやクラスの継承チェーンをたどる

module M
  A = 1
end
class C 
  include M
end
class B < C
  # Bにない → Cにない → Mにあった。
  p A # => 1
end

可変長引数、配列の展開

可変長引数メソッドの呼び出し方と内部での参照方法

def hoge(*args) # => args[0] = [1,2,3], args[1] = "a"
  p *args # => 配列を展開して表示
end
hoge([1,2,3], "a")
# => [1,2,3]
# => "a"

可変長引数を引き回し方

可変長引数を引き回す場合は展開して渡さないと配列階層が深くなってしまう。

def display(*args)
  p args
end

def non_deployment(*args)
  display(args)
end

def deployment(*args)
  display(*args)
end

non_deployment(1,2,3) # => [[1, 2, 3]]
deployment(1,2,3) # => [1, 2, 3]

通常引数と可変長引数を引数に取る

通常引数に最初の要素が設定、残りの要素が可変長引数に設定される。

def foo(a, *b)
  puts "a:#{a.inspect}, b:#{b.inspect}"
end

foo(1, 2, 3, 4)
# => a:1, b:[2, 3, 4]

省略可能な引数(オプション引数)

引数にデフォルトを設定可能

def my_method(a = 1, b = a + 1)
  p [a, b]
end

my_method(5, 6) # => [5, 6]
my_method() # => [1, 2]

デフォルト値にはメソッドの評価値も渡せる

class C
  def foo
    "foo"
  end
  def test(str = foo)
    p str
  end
end

C.new.test("bar") # => "bar"
C.new.test() # => "foo"

継承されるものされないもの

・継承される
クラスメソッド
インスタンスメソッド
クラス変数
定数

・継承されない
インスタンス変数
クラスインスタンス変数

インスタンス変数はインスタンスに依存するものでそれ以外に影響を及ぼさない。

オブジェクトの複製

dup:汚染状態、信頼状態、インスタンス変数、ファイナライザを複製
clone:dup複製内容に加えて、凍結状態(freeze)、特異メソッドを複製

上記は浅いコピーのため、
コピー先のインスタンス変数が破壊メソッドで書き換えられるとコピー元も影響を受ける

class Cat
  attr_accessor :name
  def initialize(name)
    @name = name
  end
end
 
original = Cat.new("Tama")
copied = original.clone
puts copied.equal?(original) #=> false
puts copied.name #=> Tama

copied.name.replace("Mike")
puts original.name #=> Mike

トップレベルで定義したメソッドはprivateになる

トップレベルのメソッドはObjectに定義されたメソッドと同義
Objectはすべてのクラスが継承しているため、すべてのクラスで
このメソッドをレシーバーなしで呼び出すことが可能

def my_method
  puts "my_method"
end

class C
 def c_method
   my_method
 end
end

C.new.c_method  # => my_method

参考URL

Rubyの定数、もうひとつの意外な仕様 - アインシュタインの電話番号
徒然なるままに|Rubyの継承についてのはなし(インスタンス変数,クラス変数,クラスインスタンス変数,インスタンスメソッド,クラスメソッド,定数)
clone, dup (Object) - Rubyリファレンス