ようへいの日々精進XP

よかろうもん

2018 年 05 月 11 日(金)

ジョギング

  • 香椎浜 x 2 周
  • 右足がシンスプリント気味

日課

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

奥さん

  • 宮崎に出張
  • お弁当を作って持っていってもらった

ソースコードで体感するネットワークの仕組み ~手を動かしながら基礎からTCP/IPの実装までがわかる

面白そうな本をたきぽんさんが共有されていた.

gihyo.jp

読みたい.

森田さんと呑む

  • 「もりす」にて, 串かつをつつきながら色々と話す
  • 楽しかった

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

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

Q55. 文法

以下のコードで誤りのある行を選択する.

# コード
i = 0
while i <= 5 do
  print i
  ++i
end
  1. 4 行目

以下, irb による動作確認.

irb(main):011:0> i = 0
=> 0
irb(main):012:0> while i <= 5 do
irb(main):013:1*   print i
irb(main):014:1>   ++i
0000000...

irb で実行した場合, 4 行目 ++i は無視されてしまい, 0 が出力され続ける.

以下, 解説より抜粋.

  • Ruby には ++i という構文は無い
  • インクリメントは, i += 1 等を利用する
irb(main):001:0> i = 0
=> 0
irb(main):002:0> while i <= 5 do
irb(main):003:1*   print i
irb(main):004:1>   i += 1
irb(main):005:1> end
012345=> nil

以下のように Range#each メソッドを利用して同様の結果を得ることは出来る.

irb(main):008:0> (0..5).each { |n| print n }
012345=> 0..5

Q56. メソッドの動的な定義

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

# コード
class Log
  [:debug, :info, :notice].each do |level|
    __(1)__(level) do
    define_method(level) do
      @state = level
    end
    attr_reader :state
  end
end

log = Log.new
log.debug  ; p log.state
log.info   ; p log.state
log.notice ; p log.state

# 実行結果
:debug
:info
:notice
  1. define_method

以下, irb による動作確認.

irb(main):001:0> class Log
irb(main):002:1>   [:debug, :info, :notice].each do |level|
irb(main):003:2*     define_method(level) do
irb(main):004:3*       @state = level
irb(main):005:3>     end
irb(main):006:2>     attr_reader :state
irb(main):007:2>   end
irb(main):008:1> end
=> [:debug, :info, :notice]
irb(main):009:0> 
irb(main):010:0* log = Log.new
=> #<Log:0x00559a9d9a4dd0>
irb(main):011:0> log.debug  ; p log.state
:debug
=> :debug
irb(main):012:0> log.info   ; p log.state
:info
=> :info
irb(main):013:0> log.notice ; p log.state
:notice
=> :notice

以下, 解説より抜粋.

  • define_method メソッドは引数で指定した名前のメソッドを定義するためのメソッド

Q57. Proc

以下のコードを実行したときの出力結果として正しいものを選択する.

# コード
var = lambda { puts "hello" }
p var.class
  1. Proc

以下, irb による動作確認.

irb(main):001:0> var = lambda { puts "hello" }
=> #<Proc:0x0055e95d25b380@(irb):1 (lambda)>
irb(main):002:0> p var.class
Proc
=> Proc

以下, 解説 (ドキュメント) より抜粋.

  • Kernel.#lambda と Proc.new はどちらも Proc クラスのオブジェクトを生成する
  • 生成されたオブジェクトについて, いくつか挙動が異なる
    • 引数の扱い (Kernel.#lambda の方が引数の取り扱いに厳密)
    • ジャンプ構文 (return や break) の挙動の違い

以下, ジャンプ構文の挙動を整理したもの.

return next break
Proc.new メソッドを抜ける 手続きオブジェクトを抜ける 例外が発生する
proc メソッドを抜ける 手続きオブジェクトを抜ける 例外が発生する
lambda 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける
イテレータ メソッドを抜ける 手続きオブジェクトを抜ける メソッドを抜ける

フムフム.