LoginSignup
1
0

More than 1 year has passed since last update.

[Ruby]おすすめ標準添付ライブラリ!

Last updated at Posted at 2021-05-14

はじめに

Rubyには、標準添付ライブラリというものがあります。これは、Rubyをより便利に活用出来るツールのことです。
これらを活用出来ることで、自分のプログラミングスキルの幅が広がり、メリットしかありませんので、日々の開発のぜひ参考にしてみてください!

ファイル/ディレクトリ操作を極める

Pathname

ファイルパスを表現するクラス。
※Fileクラスと同様のメソッドが使用可能。(こちらの記事を参照)

require 'pathname'

# Pathnameクラスの生成
Pathname.new('/tmp') #=> #<Pathname:/tmp>
Pathname('/tmp') #=> #<Pathname:/tmp>

home = Pathname.new('~')

# 連結する
foo = home.join('foo.txt') #=> #<Pathname:~/foo.txt>

# 部分的なパスを得る
foo.dirname #=> #<Pathname:~>
foo.basename #=> #<Pathname:foo.txt>
foo.expand_path #=> #<Pathname:/Users/tanaka/foo.txt>
foo.expand_path.parent #=> #<Pathname:/Users/tanaka>
foo.expand_path.parent.parent #=> #<Pathname:/Users>

# 文字列に変換する
foo.to_path #=> "~/foo.txt"
foo.to_s #=> "~/foo.txt"

fileutils

ファイル操作を行うための処理を集めたモジュール。

require 'fileutils'

# ファイルを再帰的にコピーする(第1引数にコピー元のファイル、第2引数にコピー先のディレクトリ)
FileUtils.cp_r('src/dir', 'dest/dir')

# コピー元を配列で指定
FileUtils.cp_r(%w(one two three), 'dest/dir')

# ファイル所有者、グループの変更
FileUtils.chown('tanaka', 'staff', 'dir')
FileUtils.chown_R('tanaka', 'staff', 'dir')

# パーミッションの変更
FileUtils.chmod(0700, 'dir')
FileUtils.chmod_R(0700, 'dir')

# ディレクトリの作成
FileUtils.mkdir('foo')
FileUtils.mkdir_p('foo/bar/baz')

# ファイルやディレクトリの移動
FileUtils.mv('foo', 'bar')

# ファイルやディレクトリの削除
FileUtils.rm_r('dir')

# ハードリンクの作成
FileUtils.ln('src', 'dest')

# シンボリックリンクの作成
FileUtils.ln_s('src', 'dest')

FileUtilsのメソッドで使用されるオプション一覧

オプション名 意味
:dereference_root trueだとシンボリックの指す内容コピー、falseはシンボリック自体コピー
:force trueだとStandardErrorを無視する
:nocreate trueだとファイルを作成しない
:noop trueだと実際の処理を行わない
:mtime 最終時刻をTimeか秒数で指定
:mode パーミッションを8進数で指定
:preserve trueだと更新時刻もコピー
:remove_destination trueだとコピーを行う前に、コピー先を削除
:secure trueだとファイルの削除にFileUtils.#remove_entry_secureを使用
:verbose trueだと詳細を出力

tmpdir

一時的な作業ディレクトリを作成出来ます。

require 'tmpdir'

# 一時ディレクトリの絶対パスを取得
Dir.tmpdir #=> "/var/folders/4h/..."

# 一時ディレクトリを作成してファイルパスを取得
dir = Dir.mktmpdir  do |dir|
  File.directory?(dir) #=> true
  dir #=>  "/var/folders/4h/..."
end

# 第1引数にディレクトリ名のプリフィックス、第2引数に親ディレクトリを指定出来る
dir = Dir.mktmpdir('prefix', '/tmp/sample')  do |dir|
  File.directory? #=> true
  dir #=>  "/tmp/sample/prefix..."
end

tmpfile

一時ファイルを作成して操作する事ができます。
※Fileクラスと同様のメソッドが使用可能。(こちらの記事を参照)

require 'tmpfile'

# 第1引数にディレクトリ名のプリフィックス、第2引数に親ディレクトリを指定出来る
path = Tempfile.open('prefix', '/tmp/sample') do |f|
  f.puts 'foobar'
  f.path
end

path #=> "/tmp/sample/..."
File.read(path) #=> "foobar\n"

# Tempfileをopenする
tmpfile = Tempfile.open('prefix', '/tmp/sample') #=> #<File:/tmp/sample/...>
tmpfile.path #=> "/tmp/sample/..."
tmpfile.close
tmpfile.close! # 再オープンできない

特定のフォーマットのテキストデータを扱う

YAML

構造化されたデータをプレーンな文字列で表現するためのデータ形式の1つです。
文字列・整数・浮動小数点・真偽値・nil・配列・ハッシュなどを表現できます!

require 'yaml'

yaml_string = <<EOS
---
remote:
  host:localhost
  port: 22
  ssh: true
  username: user
  password: null
EOS

# YAMLをオブジェクトとしてロード
p setting = YAML.load(yaml_string) #=> {"remote"=>{"host"=>"localhost", ...}

# 内容の変更
setting['remote'].update(host: 'example.com'

# オブジェクトをYAMLとしてダンプ
p YAML.dump(setting) #=> "---\nremote:\n host: example.com\n ..."

内容をYAMLとしてダンプ
p setting.to_yaml #=> "---\nremote:\n host: example.com\n ..."

JSON

YAML同様、人気のあるデータのダンプ形式の1つです。
こちらは、文字列・整数・浮動小数点・真偽値・nil・ハッシュなどを表現できます!

require 'json'

data = [1, 2.0, {key: 'value'}, nil, true, false]

# JSONをダンプする
json = data.to_json #=> "[1,2.0,{\"key\": \"value\"},null,true,false]"

# ロードする
p JSON.load(json) #=> [1, 2.0, {key: 'value'}, nil, true, false]

# TimeオブジェクトをJSONにダンプ
Time.now.to_json #=> "\"2021-05-14 12:34:56 +0900\""

# RegexpオブジェクトをJSONにダンプ
/ruby[0-9]/.to_json #=> ""\"(?-mix:ruby[0-9])\""

# ObjectオブジェクトをJSONにダンプ
Object.new.to_json #=> "{}"

# RangeオブジェクトをJSONにダンプ
(1..10).to_json #=> "\"1..10\""

# SymbolオブジェクトをJSONにダンプ
:symbol.to_json #=> "\"symbol\""

CSV

コンマと改行で区切ることで表現する形式です。

require 'csv'

# 配列をCSV形式の文字列に変換
['foo', 'bar', 'baz'].to_csv #=> "foo,bar,baz"

# CSV形式の文字列を配列に変換
'foo,bar,baz'.parse_csv #=> ["foo", "bar", "baz"]

# 複数行のCSVをparseする

data = <<EOS
foo,bar,baz
hoge,fuga,hoge
EOS

CSV.parse(data) do |row|
  puts row.join('|') #=> "foo|bar|..."
end

# ヘッダを指定する
data = <<EOS
name,age,gender
tanaka,21,man
yoko,32,woman
sato,44,man
EOS

CSV.parse(data, headers: :first_row) do |row|
  # ヘッダ名をキーにしてアクセス可能
  name = row['name']
  age, gender = row.values_at('age', 'gender')

  puts "#{name} is #{gender} (#{age})" #=> "tanaka is man (21)", ...
end

# CSVを書き出し
headers = %w(name age gender)
people = [
  ['tanaka', 21, 'man'],
  ['yoko', 32, 'woman'],
  ['sato', 44, 'man']
]

csv_str = CSV.generate('', write_headers: true, headers: headers) {|csv|
  people.each do |person|
    csv << person
  end
}

puts csv_str #=> name,age,gender,\ntanaka,21,man,...

CSV.parseに指定出来るオプション

オプション名 意味
:col_sep フィールド間のセパレータとして使用する文字列
:row_sep レコード間のセパレータとして使用する文字列
:quote_char シングルクォーとでもフォイールドを囲めるようになる
:encoding エンコーディングを指定
:unconverted_fields 変換前の行を配列で得ることができる
:headers 1行目をヘッダーとみなす
:return_headers ヘッダとみなした1行目もCSVとして読み込む
:headers_converters ヘッダ専用のコンバータをProcオブジェクトまたはシンボルを指定
:skip_blanks 空行を飛ばす
:force_quotes フィールドの生成時に必ずクォートする
:write_headers ヘッダを出力

上級者のための文字列オブジェクト

本来IOではない文字列をIOオブジェクトの代わりに用いることができます。

require 'stringio'

def read_upcase(io)
  io.read.upcase
end

io = open('|uname')
stringio = StringIO.new('tanaka')

p read_upcase(io) #=> "DARWIN\n"
p read_upcase(stringio) #=> "TANAKA"

集合を扱う

重複の内容そのコレクションを扱うことができるクラスです。
Setを用いることで、集合の比較や要素の追加などを高速で行うことができます。

require 'set'

# Enumerable#to_set
(1..5)..to_set #=> #<Set: {1,2,3,4,5}>

# Set.new
Set[1, 3, 5, 7] #=> #<Set: {1, 3, 5, 7}>
Set.new(%w(tanaka sato suzuki)) #=> #<Set: {"tanaka", "sato", "suzuki"}>

# 長さを返す
set = Set[1, 3, 5, 7]
set.length #=> 3

# 空にする
set = Set[1, 3, 5, 7]
set.clear #=> #<Set: {}>

# 空か確認
set = Set[1, 3, 5, 7]
set.empty? #=> false

# 要素の追加
set = Set[1, 3, 5, 7]
set << 10 #=> #<Set: {1, 3, 5, 7, 10}>

# 要素の削除
set = Set[1, 3, 5, 7, 10]
set.delete(10) #=> #<Set: {1, 3, 5, 7}>

# 要素が存在しなければ追加し、あれば何もしない
set = Set[1, 3, 5, 7]
set.add?(9) #=> #<Set: {1, 3, 5, 7, 9}>
set.add?(1) #=> nil

# 要素が存在すれば削除し、なければ何もしない
set = Set[1, 3, 5, 7]
set.delete(1) #=> #<Set: {3, 5, 7, 9}>
set.delete(100) #=> nil

# Setの連結
set = Set[1, 3, 5, 7]
set.merge(Set[11, 12, 13]) #=> #<Set: {1, 3, 5, 7, 9, 11, 12, 13}>

# 要素をまとめて削除
set = Set[ 1, 3, 5, 7]
set.subtract(1, 3) #=> #<Set: {5, 7}>

# 真となった要素を削除
## 何か削除されれば自信を返す
set = Set[0, 1, 2, 3, 4, 5, 6, 7]
set.reject! {|v| v.zero? } #=> #<Set{1, 2, 3, 4, 5, 6, 7}>

## 常に自身を返す
set.delete_if {|v| v.even? } #=> #<Set{1, 3, 5, 7}>

# 新たな集合を作る
a = %w(a b c).to_set
b = %w(c d e f).to_set

## どちらかに含まれる要素の集合(和集合)
p a | b #=> #<Set: {"a", "b", "c", "d", "e", "f"}>

## 両方に含まれる要素のみ集合(積集合)
p a & b #=> #<Set: {"c"}>

## 片方だけに含まれている集合(対称差)
p a ^ b  #=> #<Set: {"a", "b", "d". "e", "f"}>

## aの中でbに含まれない要素の集合(差集合)
p a - b  #=> #<Set: {"a", "b"}>

日付と時刻をもっと詳しく!

Time

require 'time'

# 時刻を表す文字列をTimeオブジェクトに変換
time = Time.parse('2021-05-14 12:34') #=> 2021-05-14 12:34:00 +9000

# 各種フォーマットで表現された文字列を返す
time.iso8601 #=> "2021-05-14T12:34:00+09:00"
time.httpdate #=> "Fri, 14 May 2021 03:34:00 GMT"
time.rfc2822 #=> "Fri, 14 May 2021 12:34:00 +0900"

# 第1引数に時刻の文字列、第2引数にフォーマットを指定して、Timeオブジェクトを生成
Time.strptime('2021年5月14日', '%Y年%m月%d日') #=> 2021-05-14 00:00:00 +0900

Date/DateTime

日付を表現するクラス。

require 'date'

# 年月日からDateオブジェクトを得る
date = Date.new(2021, 5, 14)

# 日付を指定した書式の文字列で表現
date.strftime('%Y年%m月%d日') #=> "2021年05月14日"

# 妥当な日付か真偽値で確認
Date.valid_date?(2000, 1, 1) #=> false

# うるう年か真偽値で確認
Date.leap?(2004) #=> true

# 今日の日付を取得
Date.today #=> Fri, 14 May 2021

# 年月日を確認
date.year #=> 2021
date.month #=> 5
date.day #=> 14

# TImeオブジェクトからDateTimeオブジェクトを作成
Time.new.to_date #=> Fri, 14 May 2021

おわりに

いくつかのライブラリを紹介しましたが、かなり便利な機能があったんではないでしょうか?
標準添付ライブラリを味方につけてRubyマスターになりましょう!

1
0
1

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
1
0