ようへいの日々精進XP

よかろうもん

2018 年 03 月 10 日(土)

ジョギング

  • 香椎浜 x 2 周 + 砂浜 = 45 分程
  • ラソンの疲れが抜けていない...
  • 天気も良くて香椎浜はとても走りやすかった

日課

  • (腕立て x 50 + 腹筋 x 30) x 3

居酒屋ひろみ

週末の楽しみ, 居酒屋ひろみが開店したが...

料理はどれも美味しかったけど, 要件定義はしっかりと.

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

もう何度か解いているけど, Ruby技術者認定試験【Gold】模擬問題 を数問ずつ解いていく. ポイントは, 問題が何について問われているかがちゃんと理解出来ていること.

Q44. 定数へのアクセス

以下の結果を出力するコードとして__(1)__にあてはまるものを選択してください.

# コード
CONST = "message1"
class Foo
  CONST = "message2"
  def foo
    puts __(1)__
  end
end
Foo.new.foo
# 実行結果
message1

以下, 解答.

::CONST

以下, 解説より抜粋.

  • 定数名の先頭の :: はトップレベルを表すので, ::CONST で定数にアクセスすることが出来る
  • あるクラスまたはモジュールで定義された定数を外部から参照する為には :: 演算子を利用する

ちなみに, Foo クラスの定数にアクセスする場合には...

Foo::CONST

でアクセスする.

以下, 実行例.

[1] pry(main)> CONST = "message1"
=> "message1"
[2] pry(main)> class Foo
[2] pry(main)*   CONST = "message2"  
[2] pry(main)*   def foo  
[2] pry(main)*     puts ::CONST    
[2] pry(main)*   end    
[2] pry(main)* end  
=> :foo
[3] pry(main)> Foo.new.foo
message1
=> nil
[4] pry(main)> Foo::CONST
=> "message2"

Q45. クラスの説明 

クラス変数の説明として正しいものを選択してください.

クラス変数の変数名の先頭には「@@」を付ける必要がある

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで を参考に, クラス変数挙動を確認してみる.

[1] pry(main)> class Foo
[1] pry(main)*   @@c = 'Foo'  
[1] pry(main)*   
[1] pry(main)*   def self.foo  
[1] pry(main)*     @@c    
[1] pry(main)*   end    
[1] pry(main)*   
[1] pry(main)*   def initialize(a)  
[1] pry(main)*     @@c = a    
[1] pry(main)*   end    
[1] pry(main)*     
[1] pry(main)*   def foo  
[1] pry(main)*     @@c    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :foo
[2] pry(main)> Foo.foo
=> "Foo" # クラスメソッドからもアクセス出来る
[3] pry(main)> Foo.new('bar')
=> #<Foo:0x0000563d4491cd78>
[4] pry(main)> Foo.foo
=> "bar" # インスタンス化した時点でインスタンス化した際の引数で上書きされている
[6] pry(main)> class Bar < Foo
[6] pry(main)*   @@c = 'Bar'  
[6] pry(main)*     
[6] pry(main)*   def self.foo  
[6] pry(main)*     @@c    
[6] pry(main)*   end    
[6] pry(main)* end  
=> :foo
[7] pry(main)> Bar.foo
=> "Bar" # Bar クラスを定義した時点でクラス変数 @@c は上書きされている

[1] pry(main)> class Foo
[1] pry(main)*   @@c = 'Foo'    
[1] pry(main)*     
[1] pry(main)*   def self.foo    
[1] pry(main)*     @@c        
[1] pry(main)*   end        
[1] pry(main)*     
[1] pry(main)*   def initialize(a)    
[1] pry(main)*     @@c = a        
[1] pry(main)*   end        
[1] pry(main)*       
[1] pry(main)*   def foo    
[1] pry(main)*     @@c        
[1] pry(main)*   end        
[1] pry(main)* end  
=> :foo
[3] pry(main)> Foo.foo
=> "Foo"
[4] pry(main)> Foo.new('foo').foo
=> "foo" # Foo をインスタンス化した際に上書きされる
[7] pry(main)> class Bar < Foo
[7] pry(main)*   def self.foo    
[7] pry(main)*     @@c       
[7] pry(main)*   end    
[7] pry(main)*     
[7] pry(main)*   def initialize(a)    
[7] pry(main)*     @@c = a        
[7] pry(main)*   end    
[7] pry(main)*   
[7] pry(main)*   def baz  
[7] pry(main)*     @@c    
[7] pry(main)*   end    
[7] pry(main)* end   
=> :baz
[5] pry(main)> Bar.foo
=> "foo" # サブクラスでもアクセス出来る
[8] pry(main)> Bar.new('baz').baz
=> "baz" # サブクラスをインスタンス化した際上書きされる

クラス変数は以下のような挙動となる.

実際に使ってみると, 意図しない変数の上書きが出来てしまいそうなので恐怖しか感じない.

Q46. 標準クラス, モジュール

以下のコードを実行した結果から,__(1)__にあてはまる正しいものを選択してください.

# コード
class Person
  def initialize(name)
    @name = name
  end
  def __(1)__
    "My name is #{@name}"
  end
end
p Person.new("taro")

# 実行結果
My name is taro.

以下, 解答.

inspect

以下, 解説より抜粋.

  • inspect メソッドは p メソッドでオブジェクトそのものを出力した際の文字列表現を指定するメソッド
  • p メソッドは内部的に String#inspect メソッドを呼んでいる

以下, 実行例.

class Person
  def initialize(name)
    @name = name
  end
end
p Person.new("taro")

[1] pry(main)> class Person
[1] pry(main)*   def initialize(name)  
[1] pry(main)*     @name = name    
[1] pry(main)*   end    
[1] pry(main)*   def inspect  
[1] pry(main)*     "My name is #{@name}"    
[1] pry(main)*   end    
[1] pry(main)* end  
=> :inspect
[2] pry(main)> p Person.new("taro")
My name is taro
=> My name is taro

設問では inspect メソッドを上書きしている為, My name is tar という出力となる...という理解でいいのかな...

ふむふむ.