ようへいの日々精進XP

よかろうもん

2018 年 03 月 04 日(日)

ジョギング

北島サブスリーいけもした。

  • めちゃくちゃ暑くなって, 昨年とは違ったキツさがあったけど, 鹿児島マラソン完走
  • 2 時間 57 分 25 秒でサブスリー達成
  • 奥さん, 両親をはじめ応援してくれた皆さんに感謝

  • サブスリーを達成したので, 実家でお鮨パーリー
  • ありがたや, ありがたや

帰福

  • 実家でどんちゃん騒ぎした後, 新幹線で帰福
  • おつかれちゃんでした

よしもと

  • 晩酌は「よしもと」で

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

Q26. Array クラス

以下のコードの実行結果として正しいものを選択してください.

# コード
ary = [:job1, :job2, :job3]
ary.push(:job4)
ary.unshift(:job5)
ary.pop
ary.shift
p ary

Array#push, Array#pop, Array#unshift, Array#shift はすべて配列の要素の追加と取り出しを行うメソッド.

[:job1, :job2, :job3]

以下, 実行結果.

[13] pry(main)> ary = [:job1, :job2, :job3]
=> [:job1, :job2, :job3]
[14] pry(main)> ary.push(:job4)
=> [:job1, :job2, :job3, :job4]
[15] pry(main)> ary.unshift(:job5)
=> [:job5, :job1, :job2, :job3, :job4]
[16] pry(main)> ary.pop
=> :job4
[17] pry(main)> ary.shift
=> :job5
[18] pry(main)> p ary
[:job1, :job2, :job3]
=> [:job1, :job2, :job3]

以下, 整理したもの.

メソッド 機能
Array#push 引数に指定した要素を末尾に追加
Array#pop 末尾から要素を取り除いてそれを返す
Array#unshift 引数に指定した要素を先頭に追加
Array#shift 先頭から要素を取り除いてそれを返す

Q27. Array クラス

以下のコードの実行結果として正しいものを選択してください.

# コード
ary = Array.new(3, "a")
ary[0].next!
p ary

Array.new()[] で配列を生成することが出来る.

["b", "b", "b"]

以下, 解説より抜粋.

  • Array.new は配列オブジェクトを生成する
  • new メソッドには2つの引数を指定することができ, 1 つ目には配列の要素数, 2 つ目には要素の初期値を指定する

以下, 実行例.

[19] pry(main)> ary = Array.new(3, "a")
=> ["a", "a", "a"]
[20] pry(main)> ary[0].next!
=> "b"
[21] pry(main)> p ary
["b", "b", "b"]
=> ["b", "b", "b"]

以下のように Array.new で配列を生成した場合, 各要素は同一のオブジェクトを参照するので注意が必要.

[1] pry(main)> ary = Array.new(3, "a")
=> ["a", "a", "a"]
[2] pry(main)> ary[0].next!
=> "b"
[3] pry(main)> p ary
["b", "b", "b"]
=> ["b", "b", "b"]
[4] pry(main)> ary = ['a', 'a', 'a']
=> ["a", "a", "a"]
[5] pry(main)> ary[0].next!
=> "b"
[6] pry(main)> p ary
["b", "a", "a"]
=> ["b", "a", "a"]

Q28. Array クラスオブジェクトのソート

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

# コード
class MyNum
 attr_reader :num
 def initialize(num)
  @num = num
 end
 __(1)__
end

num1 = MyNum.new(30)
num2 = MyNum.new(10)
num3 = MyNum.new(20)
p [num1, num2, num3].sort.map{|n| n.num }

# 実行結果
[10, 20, 30]

以下を定義する.

def <=>(other)
  @num <=> other.num
end

以下, 解説より抜粋.

  • 設問のコードでは配列に対して sort メソッドを呼び出している
  • sort メソッドは, 配列の要素に対して <=> 演算子を使用して比較する
  • 数値や文字列などの既存のオブジェクトに関しては, <=> 演算子が定義されているので sort メソッドを利用することが出来る
  • 設問のクラスオブジェクトについては <=> 演算子を再定義する必要がある

若干, 理解に苦しんだので, 以下のように順を追って動作確認してみた.

[1] pry(main)> class MyNum
[1] pry(main)*   attr_reader :num 
[1] pry(main)*   def initialize(num) 
[1] pry(main)*     @num = num  
[1] pry(main)*   end   
[1] pry(main)* end  
=> :initialize
[2] pry(main)> num1 = MyNum.new(30)
=> #<MyNum:0x000055ac56ff6f60 @num=30>
[3] pry(main)> num2 = MyNum.new(10)
=> #<MyNum:0x000055ac56fac528 @num=10>
[4] pry(main)> num3 = MyNum.new(20)
=> #<MyNum:0x000055ac56f69c00 @num=20>
# オブジェクト同士を比較して sort しようとしているけど, <=> 演算子が無いので例外となる
[5] pry(main)> [num1, num2, num3].sort
ArgumentError: comparison of MyNum with MyNum failed
# <=> 演算子を再定義
[6] pry(main)> class MyNum
[6] pry(main)*   def <=>(other)
[6] pry(main)*     @num <=> other.num  
[6] pry(main)*   end  
[6] pry(main)* end  
=> :<=>
[7] pry(main)> [num1, num2, num3].sort
=> [#<MyNum:0x000055ac56fac528 @num=10>, #<MyNum:0x000055ac56f69c00 @num=20>, #<MyNum:0x000055ac56ff6f60 @num=30>]
[8] pry(main)> [num1, num2, num3].sort.map {|o| o.num }
=> [10, 20, 30]

ふむふむ.

Q29. オブジェクトの比較

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

# コード
var1 = __(1)__
var2 = __(1)__
puts var1.equal?(var2)

# 実行結果
true

:hello

以下, 解説より抜粋.

  • Object#equal? はオブジェクト同士の同一性判定用のメソッドで引数で指定したオブジェクトがレシーバ自身であれば true を返す
  • :hello はシンボルオブジェクトを表しているので, 文字列が同じであれば同じオブジェクトを参照する

以下, 実行例.

[9] pry(main)> var1 = :hello
=> :hello
[10] pry(main)> var2 = :hello
=> :hello
[11] pry(main)> puts var1.equal?(var2)
true
=> nil
[17] pry(main)> var1.object_id
=> 2846108
[18] pry(main)> var2.object_id
=> 2846108
[12] pry(main)> var1 = :hello
=> :hello
[13] pry(main)> var2 = :hell
=> :hell
[14] pry(main)> puts var1.equal?(var2)
false

Q30. 変数展開

以下のコードを実行したときの結果として正しいものを選択してください.

# コード
a, b = [1, 2, 3]
p a
p b

以下のような結果になる.

1
2

以下, 解説より抜粋.

  • 左辺の変数の数より, 右辺の値の数の方が多い場合は残りの値を破棄する

以下, 実行例.

[20] pry(main)> a, b = [1, 2, 3]
=> [1, 2, 3]
[21] pry(main)> p a
1
=> 1
[22] pry(main)> p b
2
=> 2

ちなみに, 左辺の変数に * をつけた場合には以下のようになる.

[23] pry(main)> a, *b = [1, 2, 3]
=> [1, 2, 3]
[24] pry(main)> p a
1
=> 1
[25] pry(main)> p b
[2, 3]
=> [2, 3]
[29] pry(main)> *a, b = [1, 2, 3]
=> [1, 2, 3]
[30] pry(main)> p a
[1, 2]
=> [1, 2]
[31] pry(main)> p b
3
=> 3
[32] pry(main)> *a = [1, 2, 3]
=> [1, 2, 3]
[33] pry(main)> p a
[1, 2, 3]
=> [1, 2, 3]