標準ライブラリ【パーフェクトRuby Part4】


関東の大雪でめっちゃ寒いですが、『パーフェクト Ruby』を少しずつですが読み進めています。ここでは『Part3のメタプログラミング』に引き続いて、Part4の標準ライブラリで特に気になった部分をメモしていきます!


🎳 ファイルパスを表現するクラス: Pathname

ファイルパスを表現するクラス「Pathname」はファイルパスをオブジェクト指向らしく扱うことができるクラスです。

require 'pathname'
home = Pathname.new('~')
foo = home.join('foo.txt')
p foo #=> #<Pathname:~/foo.txt>
p foo.dirname #=> #<Pathname:~>
p foo.basename #=> #<Pathname:foo.txt>
p foo.expand_path #=> #<Pathname:/Users/komji/foo.txt>
p foo.expand_path.parent #=> #<Pathname:/Users/komji>
p foo.expand_path.parent.parent #=> #<Pathname:/Users>

このほかにもファイルの属性などを簡単に習得することもできます。詳しくはこちらの「リファレンス」を

🎉 ファイル操作: FileUtils

FileUtils」はファイル操作を行ための処理を集めたモジュールです。

require 'fileutils'
# ディレクトリ内のファイルを別のディレクトリにコピー
FileUtils.cp_r 'from/dir', 'to/dir'
# ファイル所有者変更
FileUtils.crown_R 'user_name', 'group_name', 'dir'
# ディレクトリの作成
FileUtils.mkdir_p 'hoge/huga/foo'
# ハードリンクの作成
FileUtils.ln 'source', 'destination'
# シンボリックリンクの作成
FileUtils.ln_s 'source', 'destination'

🗽 一時作業ディレクトリ: tmpdir

複数のファイルを順次作成して全てそろってから結合作業を行う場合などは、一時的な作業ディレクトリが必要になることがあります。そんなときに「tmpdirライブラリ」が役に立ちます。

require 'tmpdir'
path = Dir.mktmpdir('prefix')
puts path #=> /var/folders/yd/z2mfpb7n4g98gmcbtxn17wnr0000gn/T/prefix20140209-16518-1kzz0zb
puts File.directory?(path) #=> 1

🗻 一時ファイル: tmpfile

アップロードされたファイルの内容を一時的にファイルに書き込んでそれを元に操作を行うような場合、一時ファイルを必要とすることがあります。そのときにこの『**tmpfileライブラリ』が役に立ちます。

require 'tempfile'
path = Tempfile.open(['hoge', 'bar']) do |f|
f.puts 'foobar'
f.path
end
puts path #=> /var/folders/yd/z2mfpb7n4g98gmcbtxn17wnr0000gn/T/hoge20140209-17075-1t7lsy2bar
puts File.read(path) #=> foobar

😀 Timeクラスの拡張: time

Rubyの組込みラスのTimeを拡張する標準ライブラリとして「time」があります。

require 'time'
# Time#parseはTimeオブジェクトを返す
puts Time.parse('2011-04-01 16:01').class #=> time
puts Time.parse('Sun, 29 Jan 2012 14:14:09 +0900') #=> 2012-01-29 14:14:09 +0900
puts Time.parse('2013012914144909') #=> 2013-01-29 09:14:49 +0900
###############################
time = Time.parse('2011-04-01 16:01')
# 各種フォーマットに対応した文字列を返す
puts time.iso8601 #=> 2011-04-01T16:01:00+09:00
puts time.httpdate #=> Fri, 01 Apr 2011 07:01:00 GMT
puts time.rfc2822 #=> Fri, 01 Apr 2011 16:01:00 +0900
# 様々なフォーマットの文字列をパースする
puts Time.iso8601('2011-04-01T16:01:00+09:00') #=> 2011-04-01 07:01:00 UTC
puts Time.httpdate('Fri, 01 Apr 2011 07:01:00 GMT') #=> 2011-04-01 16:01:00 +0900

🍮 日付を表現: Dateクラス

日付を表現するDateクラスは日付計算をかなり便利にやってくれます。

require 'date'
# 年月日から日付オブジェクトを取得
date = Date.new(2011, 4, 1)
#=> #<Date: 2011-04-01 ((2455653j,0s,0n),+0s,2299161j)>
# 曜日(番号)を取得
date.wday #=> 5
# 日付 => 指定したフォーマットの文字列に変換
date.strftime('%Y/%m/%d %H:%M:%S') #=> "2014/02/16 00:00:00"
# 現在の日時オブジェクトを取得
date = Date.today #=> #<Date: 2014-02-16 ((2456705j,0s,0n),+0s,2299161j)>
# n日後
date.next_day(3) #=> #<Date: 2011-04-04 ((2455656j,0s,0n),+0s,2299161j)>
# n日前
date.prev_day(3) #=> #<Date: 2011-03-29 ((2455650j,0s,0n),+0s,2299161j)>
# nヶ月後
date.next_month(2) #=> #<Date: 2011-06-01 ((2455714j,0s,0n),+0s,2299161j)>
# n年前
date.prev_year(3) #=> #<Date: 2008-04-01 ((2454558j,0s,0n),+0s,2299161j)>

🐹 日付と時刻を表現: DateTimeクラス

Dateクラスを継承して、時刻情報も扱うことができるDateTimeクラスを紹介します。

require 'date'
# 年月日時分秒からDateTimeオブジェクトを取得
date = DateTime.new(2011, 4, 1, 4, 4, 25)
#=> #<DateTime: 2011-04-01T04:04:25+00:00 ((2455653j,14665s,0n),+0s,2299161j)>
# 様々な書式で出力
date.httpdate #=> "Fri, 01 Apr 2011 04:04:25 GMT"
date.iso8601 #=> "2011-04-01T04:04:25+00:00"
# 様々な書式をパースする
DateTime.httpdate('Tue, 3 Jul 2012 12:08:43 GMT')
#=> #<DateTime: 2012-07-03T12:08:43+00:00 ((2456112j,43723s,0n),+0s,2299161j)>
DateTime.rfc3339('2012-07-03T22:09:44+09:00')
#=> #<DateTime: 2012-07-03T22:09:44+09:00 ((2456112j,47384s,0n),+32400s,2299161j)>

😼 ベンチマークを簡単に測定できる: benchmark

Rubyでプログラムの実行時間を計測するためのライブラリがbenchmarkです。

require 'benchmark'
n = 10000000
Benchmark.bm(7, '>total:', '>avg:') do |x|
f = x.report('for:') { for i in 1..n; val = 'value' end }
w = x.report('while:') { i = 1; while i <= n; val = 'value'; i += 1 end }
t = x.report('times:') { n.times do val = 'value' end }
total = f + w + t
average = total / 3
[total, average]
end

このプログラムの実行結果がこちら。

              user     system      total        real
for:      1.070000   0.010000   1.080000 (  1.072397)
while:    0.690000   0.000000   0.690000 (  0.695177)
times:    1.070000   0.000000   1.070000 (  1.064100)
>total:   2.830000   0.010000   2.840000 (  2.831674)
>avg:     0.943333   0.003333   0.946667 (  0.943891)

📚 おすすめの書籍

🖥 サーバについて

このブログでは「Cloud Garage」さんのDev Assist Program(開発者向けインスタンス無償提供制度)でお借りしたサーバで技術検証しています。 Dev Assist Programは、開発者や開発コミュニティ、スタートアップ企業の方が1GBメモリのインスタンス3台を1年間無料で借りれる心強い制度です!(有償でも1,480円/月と格安)