ようへいの日々精進XP

よかろうもん

2018 年 04 月 25 日(水)

ジョギング

日課

  • 今日はお休み

夕飯

  • 俺達の「よしもと」へ
  • こじまさんと久しぶりにお話した
  • イカゲソの天ぷらをおまけして頂いた

shunit2

少し時間が出来たので, shunit2 を触ってみた.

今日のるびぃ ~ Ruby技術者認定試験【Gold】模擬問題を解いてみる (re: 4) ~

もう何度か解いているけど, 再び, Ruby技術者認定試験【Gold】模擬問題 を 3 ~ 5 問くらいずつ解いていく.

Q10. オブジェクト指向

以下の実行結果にならないようにするために __(1)__ に当てはまるものを選択する.

# コード
class Foo
  def bar(obj=nil)
   __(1)__
 end
 protected
 def foo
   puts "foo"
 end
end
Foo.new.bar(Foo.new)


# 実行結果
foo

Foo.foo

以下, irb での実行例.

irb(main):001:0> class Foo
irb(main):002:1>   def bar(obj=nil)
irb(main):003:2>     Foo.foo
irb(main):004:2>  end
irb(main):005:1>  protected
irb(main):006:1>  def foo
irb(main):007:2>    puts "foo"
irb(main):008:2>  end
irb(main):009:1> end
=> :foo
irb(main):010:0> Foo.new.bar(Foo.new)
NoMethodError: undefined method `foo' for Foo:Class

以下, 解説より抜粋.

  • protected 以降で定義されたメソッドは, そのクラスとサブクラスのインスタンスから呼び出しが可能
  • protected 以降で定義されたメソッドは, クラスをレシーバとして呼び出すことは出来ない為, Foo.foo はエラーとなる

実行結果の通りになるコードを irb で確認.

irb(main):001:0> class Foo
irb(main):002:1>   def bar(obj=nil)
irb(main):003:2>     foo
irb(main):004:2>  end
irb(main):005:1>  protected
irb(main):006:1>  def foo
irb(main):007:2>    puts "foo"
irb(main):008:2>  end
irb(main):009:1> end
=> :foo
irb(main):010:0> Foo.new.bar(Foo.new)
foo

irb(main):001:0> class Foo
irb(main):002:1>   def bar(obj=nil)
irb(main):003:2>     self.foo
irb(main):004:2>  end
irb(main):005:1>  protected
irb(main):006:1>  def foo
irb(main):007:2>    puts "foo"
irb(main):008:2>  end
irb(main):009:1> end
=> :foo
irb(main):010:0> Foo.new.bar(Foo.new)
foo

irb(main):011:0> class Foo
irb(main):012:1>   def bar(obj=nil)
irb(main):013:2>     obj.foo
irb(main):014:2>  end
irb(main):015:1>  protected
irb(main):016:1>  def foo
irb(main):017:2>    puts "foo"
irb(main):018:2>  end
irb(main):019:1> end
=> :foo
irb(main):020:0> Foo.new.bar(Foo.new)
foo

Q11. オブジェクト指向

以下のコードの実行結果から __(1)__ に当てはまるものを選択する.

# コード
class Foo
  def __(1)__
   puts "foo"
 end
end
Foo.foo

# 実行結果
foo

Foo.foo

以下, irb での実行結果.

irb(main):001:0> class Foo
irb(main):002:1>   def Foo.foo
irb(main):003:2>    puts "foo"
irb(main):004:2>  end
irb(main):005:1> end
=> :foo
irb(main):006:0> Foo.foo
foo
=> nil

以下, 解説より抜粋.

  • クラスメソッドはクラスをレシーバにして呼び出すことが出来る
  • クラスメソッドは クラス.メソッド の形式で定義する (他にも以下のような定義の方法がある)
# 1
class HelloWorld
  class << self
    def hello
      'Hello, World!'
    end
  end
end

# 2
class HelloWorld; end
def self.hello
  'Hello, World!'
end

# 3
module Greeting
  def hello
    'Hello, World!'
  end
end

class HelloWorld
  extend Greeting
end

Q12. オブジェクト指向

以下のコードを実行した結果を選択する.

# コード
class Foo
  def foo
    self
  end
end
class Bar < Foo
  def bar
    foo
  end
end
p Bar.new.bar.class

Bar

以下, irb による実行例.

irb(main):001:0> class Foo
irb(main):002:1>   def foo
irb(main):003:2>     self
irb(main):004:2>   end
irb(main):005:1> end
=> :foo
irb(main):006:0> class Bar < Foo
irb(main):007:1>   def bar
irb(main):008:2>     foo
irb(main):009:2>   end
irb(main):010:1> end
=> :bar
irb(main):011:0> p Bar.new.bar.class
Bar
=> Bar

以下, 解説より抜粋.

  • Bar クラスは Foo クラスを継承しているので, Bar クラスのインスタンスから foo メソッドを呼ぶことが出来る
  • foo メソッド内にある self は, bar メソッドを呼び出した Bar クラスのオブジェクトを参照する
  • このオブジェクトに対して class メソッドが呼ばれる為, Bar が出力される

self キーワードについて (Ruby技術者認定試験【Gold】模擬問題 より抜粋).

  • self キーワードはインスタンス自身を表す
  • メソッドを呼び出す場合には暗黙的に self に対してメソッドを呼び出している為, self は省略可能
irb(main):012:0> class Foo
irb(main):013:1>   puts "クラス直下 self: #{self}"
irb(main):014:1>   def self.bar
irb(main):015:2>     puts "クラスメソッド直下 self: #{self}"
irb(main):016:2>   end
irb(main):017:1> end
クラス直下 self: Foo
=> :bar
irb(main):018:0> class Foo
irb(main):019:1>   def baz
irb(main):020:2>     puts "インスタンスメソッド内 self: #{self}"
irb(main):021:2>   end
irb(main):022:1> end
=> :baz
irb(main):023:0> Foo.bar
クラスメソッド直下 self: Foo
=> nil
irb(main):024:0> Foo.new.baz
インスタンスメソッド内 self: #<Foo:0x00555bb6d1fe68>
=> nil
  • クラス直下, クラスメソッド内での self は Foo と表示されており, 「Foo クラス自身」を表している
  • インスタンスメソッド内での self は #<Foo:0x00555bb6d1fe68> と出力されているが, これは「Foo クラスのインスタンス」を表している

フムフム.