tl;dr
かなり古い WEB+DB PRESS (2011 Vol.63) の連載 (Ruby わくわくナビ第 1 回) にて, ライブラリの使い方を知る (学ぶ) 為にテストコードを書くことで, 単にサンプルコードを書き捨てるよりも, 「繰り返して実行可能」, 「いつでも参照可能」な自分用のリファレンスを作ることが出来るというメリットがあると書かれていた.
ということで, 組み込みライブラリ (クラス) のメソッドについて, 学習テストを書いていきつつ, メソッドの使い方を学んでいきたいと思う.
尚, 上述の記事では, Ruby 1.9 に追加されたメソッド達について触れられていたが, 本記事では Object クラスをスーパークラスとする各サブクラス全部を対象としていきたいと考えている.
どのクラスのどのメソッドにするのか
出来るだけ, 多くのメソッド達に触れていきたいと思いつつ, どうやって学習するクラスのメソッドを決めようと悩んだ末に, 以下のようなランダムに組み込みライブラリのメソッドを返すコードを書いた.
#!/usr/bin/env ruby # file name: gacha.rb class Class def subclasses subclasses = [] ObjectSpace.each_object(singleton_class) do |k| subclasses << k if k.superclass == self end subclasses end end c = Object.subclasses.sample methods_list = c.instance_methods(false).sample(3) puts "クラス: #{c}" methods_list.each { |m| puts "メソッド: #{m}" }
名づけて, メソッドガチャ. 本来の「ガチャ」を引く, 「ガチャ」を回すという言葉の意味はちゃんと理解出来ていないんだけど, 「クジを引く」くらいの意味を込めてみた. で, このメソッドガチャを実行して, 出力されたメソッド (インスタンスメソッド) について学習していく. ちなみに, サブクラスの取得方法については, 以下の記事を参考にさせて頂いた. 感謝.
このガチャを回すと以下のように出力される.
$ ruby gacha.rb
クラス: Dir
メソッド: close
メソッド: each
メソッド: tell
$ ruby gacha.rb
クラス: MatchData
メソッド: ==
メソッド: offset
メソッド: begin
$ ruby gacha.rb
クラス: Enumerator
メソッド: feed
メソッド: size
メソッド: rewind
なんか面白い.
進め方
本記事については, 以下のように進める.
- ガチャを引く
- 出力されたメソッドの中から 1 ~ 3 つ選んで, そのメソッドについてリファレンスを確認する
- テストコードを書いて, 挙動を確認する
書いた学習コードは, 以下の Github リポジトリで管理する.
尚, 本記事で扱う環境は以下の通り. テストを書く場合には, Rspec または minitest を利用して書いていく. 特に明記しない場合には多分 minitest を利用する.
$ ruby --version ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] $ bundle exec rspec --version RSpec 3.7 - rspec-core 3.7.1 - rspec-expectations 3.7.0 - rspec-mocks 3.7.0 - rspec-support 3.7.1 $ bundle exec irb --version irb 0.9.6(09/06/30) $ bundle exec irb irb(main):001:0> require 'minitest/autorun' => true irb(main):002:0> MiniTest::Unit::VERSION => "5.11.3"
ということで, 第一回目
ガチャを回す
$ ruby gacha.rb クラス: Time メソッド: tv_sec メソッド: gmt_offset メソッド: utc_offset
この中から Time#tv_sec (Time#to_i) と Time#utc_offset (Time#gmt_offset) について学習テストしていく.
Time#tv_sec とは
以下, ドキュメントから引用.
起算時からの経過秒数を整数で返します。
to_i -> Integer tv_sec -> Integer
上記の通り, to_i メソッドと同義で, レシーバで指定した Time オブジェクトの整数値を返す.
Time#tv_sec の 学習テスト
以下のように書いた.
require 'minitest/autorun' require "minitest/reporters" Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new] class GakushuTest < Minitest::Test def test_time_tv_sec assert_equal Time.new(2017, 11, 12, 1, 2, 3).tv_sec.class, Integer end def test_time_to_i assert_equal Time.new(2017, 11, 12, 1, 2, 3).to_i.class, Integer end en
Time.new で Time オブジェクトを生成して, .tv_sec
及び to_i
の結果が整数値であることを確認している.
$ bundle exec ruby 2018/05/06.rb Started with run options --seed 62380 GakushuTest test_time_tv_sec PASS (0.00s) test_time_to_i PASS (0.00s) Finished in 0.00092s 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
irb でも確認してみる.
irb(main):005:0> Time.new(2017, 11, 12, 1, 2, 3).tv_sec.class => Integer irb(main):006:0> Time.new(2017, 11, 12, 1, 2, 3).tv_sec => 1510416123 irb(main):007:0> Time.new(2017, 11, 12, 1, 2, 3).to_i.class => Integer irb(main):008:0> Time.new(2017, 11, 12, 1, 2, 3).to_i => 1510416123
フムフム.
Time#utc_offset とは
以下, ドキュメントより引用.
協定世界時との時差を秒を単位とする数値として返します。 地方時が協定世界時よりも進んでいる場合(アジア、オーストラリアなど) には正の値、遅れている場合(アメリカなど)には負の値になります。
utc_offset -> Integer gmt_offset -> Integer gmtoff -> Integer
協定世界時 (UTC) と地方時 (例えば, 日本標準時) の差分を秒で返す. gmt_offcet
や gmtoff
でも同様の結果を返す.
Time#utc_offset の学習テスト
日本標準時は協定世界時 (UTC) に 9 時間 (60 * 60 * 9 = 32400) 加算した時刻となる為, Time#utc_offset の結果は 32400 となることを期待するので, 以下のようなテストコードを書いた.
require 'minitest/autorun' require "minitest/reporters" Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new] class GakushuTest < Minitest::Test def test_time_zone assert_equal Time.now.zone, 'JST' end def test_time_utc_offset assert_equal Time.now.utc_offset, 32400 end def test_time_gmt_offset assert_equal Time.now.gmt_offset, 32400 end def test_time_gmtoff assert_equal Time.now.gmtoff, 32400 end end
テストを走らせると以下のように出力される. ちなみに, 任意のテストメソッドだけ実行したい場合には -n
オプションを利用する. また -n
オプションは正規表現が利用可能なのが嬉しい.
$ bundle exec ruby 2018/05/06.rb -n test_time_zone -n /off/ Started with run options -n test_time_zone -n /off/ --seed 50955 GakushuTest test_time_utc_offset PASS (0.00s) test_time_gmt_offset PASS (0.00s) test_time_gmtoff PASS (0.00s) Finished in 0.00091s 3 tests, 3 assertions, 0 failures, 0 errors, 0 skips
irb でも確認する.
irb(main):001:0> Time.now => 2018-05-06 14:00:47 +0900 irb(main):002:0> Time.now.zone => "JST" irb(main):003:0> Time.now.utc_offset => 32400 irb(main):004:0> Time.now.gmt_offset => 32400 irb(main):005:0> Time.now.gmtoff => 32400
フムフム.
以上
いつまで続くかわからないけど, 多くのメソッドとの出会いを楽しみにしている.