LoginSignup
3
1

More than 5 years have passed since last update.

Rubyクイズ 答えと解説

Last updated at Posted at 2016-12-12

こちらのクイズの答えと解説(?)です。

ruby 2.3.0で動作確認しています。

クイズ1

Aの出力結果は何でしょう?

def hoge(options = {})
  foo = options.delete(:foo)
  puts "foo is #{foo}"
  puts "options is #{options}"
end

options = {foo: 'FOO', bar: 'BAR'}
hoge(options)
puts options #=> A

答え

Aの出力結果 : {:bar=>"BAR"}

解説

rubyは参照の値渡しを行いますので、引数を受け取った先(#hoge)で引数の破壊的な変更を行うと、
メソッドの呼び出しもとに影響があります。
#deelte!はついていませんが破壊的メソッドなので注意です。

クイズ2

A, Bの出力結果は何でしょう?

INIT_STR = 'INIT STR:'

def hoge(num)
  temp = INIT_STR
  num.times do |n|
    temp << " #{n}"
  end
  temp
end

puts hoge(3) #=> A
puts hoge(3) #=> B

答え

Aの出力結果 : INIT STR: 0 1 2
Bの出力結果 : INIT STR: 0 1 2 0 1 2

解説

rubyは定数を書き換えてもエラーになりません。
<<メソッドでは値を書き換えてしまうので、このクイズの場合、実行するたびにINIT_STRが書き代わってしまします。

#freezeをつけておくと定数の変更はできなくなるので、必ず付けるようにすると良いでしょう。

INIT_STR = 'INIT STR:'.freeze

クイズ3

Aの出力結果は何でしょう?

def hoge(options = {}, foo: 'FOO')
  puts options
  puts foo
end

hoge(bar: 'bar', foo: 'foo') #=> A

答え

Aの出力結果 : `hoge': unknown keyword: bar (ArgumentError)

解説

詳しく追っていないのですが、デフォルト引数とキーワード引数を併用するときは注意。

クイズ4

A〜Hの実行結果は何でしょう?

Array(1)            # => A
Array(nil)          # => B
Array([])           # => C
Array.new           # => D
Array.new(1)        # => E
Array.new(nil)      # => F
Array.new(nil.to_i) # => G
Array.new([])       # => H

答え

Aの出力結果 : [1]
Bの出力結果 : []
Cの出力結果 : []
Dの出力結果 : []
Eの出力結果 : [nil]
Fの出力結果 : no implicit conversion from nil to integer (TypeError)
Gの出力結果 : []
Hの出力結果 : []

解説

Arrayメソッドは引数で受け取った値を値として持つ配列を返します。

Array("test") #=> ["test"]

引数の値はすでに配列の場合はそのまま返します。

Array(["test"]) #=> ["test"]

Array.newは受け取った第1引数の数だけ、第2引数の値を持つ配列を返します。第2引数のデフォルト値はnilです。

Array.new(3) # => [nil, nil, nil]

ちなみにnil.to_iは0になります。

クイズ5

Aの実行結果は何でしょう?

class Hoge
  def foo
    self.bar
  end

private

  def bar
    puts 'bar'
  end
end

Hoge.new.foo # => A

答え

private methodbar' called for #Hoge:0x007fe96a07cde8 (NoMethodError)`

解説

rubyのprivateメソッドは「レシーバを指定して実行できない」メソッドなので、たとえselfでも付けることはできません。
初学者が引っかかりやすいので注意。

クイズ6

Aの実行結果は何でしょう?

class Hoge
  attr_accessor :foo,

  def initialize(foo)
    @foo = foo
    puts @foo
  end
end

Hoge.new('bar') # => A

答え

wrong number of arguments (given 1, expected 0) (ArgumentError)

解説

2行目に余計な,がついているのでエラーになるのですが、何故かエラー箇所が10行目になります。
なんででしょうね。

クイズ7

A, Bの実行結果は何でしょう?

def hoge
  sleep 1 # 重い処理
  'hoge'
end

if result1 = hoge
  puts result1 # => A
end
puts result2 if result2 = hoge # => B

答え

Aの実行結果 : hoge
Bの実行結果 : undefined local variable or method `result2' for main:Object (NameError)

解説

ifをインラインで書いたときのそうでないときにスコープが若干違うようです。
インラインで書いたときにはifの条件式で新しく定義した変数は他で使えないようです。

詳しい理由をstackoverflowで教えてもらいました(1年越しの追記)。

3
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1