マニュアル: Ruby

投稿日: 更新日:

インストール

rbenvが良さそうです。

よく使うもの

文法

case

他の言語ではswitch文に相当するもの。

  • 制御構造 (Ruby 2.6.0)

  • case〜when(複数)〜else〜end

  • breakは不要(バグを引き起こしにくい)

  • whenはカンマ区切りで複数指定可能

  • 比較には === 演算子が使われる

演算子式

演算子式

  • 多重代入
    • a, b, cのようにカンマで区切る。
    • 右辺は複数の式、あるいは配列。
    • a, b, *cのように最後に*を付けると、残り全部が入る

ブロック付きメソッド

記述方法

以下の2通りの記述が可能。

[1..3].each {|i|
  ...
}
[1..3].each do |i|
  ...
end

違いは以下だけのようです。

{ … } の方が do … end ブロックよりも強く結合します。

自分はハマったことないですが(どちらかと言えば中括弧使うので)、 これで挙動が変わるケースもあります。

制御

ブロックの中でreturnをすると、ブロック自体を抜けてしまう。 値を返して次のループを回す場合は、next(next, next val)を使う。

ヒアドキュメント

ヒアドキュメント (行指向文字列リテラル)

基本

str = <<EOS
  abc
  def
  #{3+2}
EOS

結果はprint " abc\n def\n 5\n"と同じになります。 <<EOS<<"EOS"と書いても同じです。

変数展開なし

str = <<'EOS'
  abc
  def
  #{3+2}
EOS

#{3+2}のところが展開されません。

コマンド実行

str = <<`EOS`
  expr 3 + 2
EOS

文字列の中を実行します。

終端行をインデント可能にする

str = <<-EOS
  abc
  def
  #{3+2}
  EOS

先頭の空白を除く

これまでの例では先頭に2つのスペースが入っていましたが、 以下のようにすると、スペース2つが取り除かれます。 (改行のみの行は無視)

str = <<~EOS
  abc
  def

  #{3+2}
EOS

例外

呼び出し元で処理させたい場合は自前で例外クラスを作る、 それ以外は単にraiseを使ってRuntimeExceptionを投げるのでいいと思います。

数値

乱数

Kernel#randを使う。

rand      # 0〜1までの実数
rand(2)   # 0 or 1
rand(100) # 0〜99

初回呼び出し時にはKernel#srandを使って、 乱数の種を初期化する。

文字列

  • class String
  • 分割: String#split
    • 改行コード(LF)で分割: str.split("\n")
  • 数値に変換
    • 安全でない: to_i (“foo”.to_i => 0となってしまう)
    • 安全: Integer(str)
      • 変換できないときはArgumentErrorが投げられる
  • 文字列の検索: String#index
  • 文字列が含まれている(Javaだとcontains): String#include?
  • start_with?(*prefixes) -> bool: 先頭がprefixesのいずれかのときtrue
  • end_with?(*strs) -> bool: 末尾がstrsのいずれかのときtrue
  • 最初と最後の1文字を削除: str = str.slice(1..-2)
  • フォーマット: String#%
    • 例: "%4d" % i

正規表現

RegExp#match の使用例

re = Regexp.compile("正規表現文字列")
match_data = re.match(str)
if match_data == nil then
  # マッチしなかったとき
end

RegExp#match の使用例2 iTunesのURLから、idを取得する方法。

id = %r|/id([0-9]+)|.match(url)[1]

多言語化

他のソフトのほとんどは内部エンコーディングにUnicode(UTF-8、古いものはUTF-16)を使用しているが、RubyはCSI(Code Set Independent)方式を採用している。

使ってみると難しくないです。

  • デフォルトで外部エンコーディングはロケールを見るので、例えば「viで開いて文字化けしないファイル」には指定は不要。
  • エンコーディングが不明なものはforce_encodingを使って指定する。
    • force_encoding
    • 使うのは限られたケースとなっていますが、例としてHTTP通信やXMLを挙げているので、利用機会は多いです。
  • よく使うメソッド

エンコーディングのリスト

以下のコマンドで取得可能。

ruby -e "puts Encoding.list" | sort

環境変数

ENV['FOO']

文字列はfreezeされている(変更不可)

Array

Hash

以下の記法が推奨されるようです(RuboCop曰く)。

{ a:"A", b:"B", c:"C" }

でも文字列とシンボルは違うものなので、Hashのキーとしては混乱の元ですね。。。

日付処理


  • 今日の00:00:00: Date.today
  • 昨日の00:00:00: Date.today - 1
  • Date -> Time: date.to_time
  • Dateの書式指定: Date#strftime, Time#strftime
    • 書式はTime#strftimeにまとまっている。
      • %Y: 4桁の年(例: 1997)
      • %m: 2桁の月(01〜12)
      • %d: 2桁の日(01〜31)
      • %H: 2桁の時(00〜23)
      • %M: 2桁の分(00〜59)
      • %S: 2桁の秒(00〜60)
  • 日本語の曜日: %w(日 月 火 水 木 金 土)[time.wday] (日本語曜日入り日付フォーマットを1行で書く - Qiitaより)
    • %w()は配列を表す記法です(%記法)。
  • 解析
    • Time#parse
      • require 'time'しないと使えないのに注意。
    • より柔軟な表現が欲しい場合はChronicを使う。

Enumerable

ネット

URL/URI

  • URI
  • URI::HTTP
    • schemaなどのコンポーネントから作成する場合はこちら。

HTTP

httpsでの送信

def send_post(url, params)
  uri = URI.parse(url)
  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = true

  req = Net::HTTP::Post.new(uri.path)
  req.set_form_data(params)

  res = https.request(req)
  p res
end

HTML/XML

Nokogiri

以下のように使います。 オブジェクトは以下のようになります。

require 'nokogiri'

# 文字列
Nokogiri::HTML(str)

# ファイル
File.open(file) { |f|
  Nokogiri::HTML(f)
}

# open-uri
require 'open-uri'
Nokogiri::HTML(open(url))

# タイトルの取得
Nokogiri::HTML(open(url)).title

パス関連

JSON

JSONクラス

  • 準備: require 'json'
  • JSONファイルの読み込み: JSON.parse(str)
    • JSON.parse(str, {:symbolize_names => true}) とすると、文字列をシンボルにしてくれる。

引数

  • ARGV
    • ARGV[0]が最初の引数。
  • 複雑な場合はThorを使うと良い。
    • ちなみにThorはトールと呼び、雷神の名前のようです。

テスト

  • test/unitは2.2から自前でインストールしないと使えない。
    • gem install test-unitでインストール可能。
  • minitestが良さそう。

入出力

  • 標準入力: $stdinまたはSTDIN
  • 標準出力: $stdoutまたはSTDOUT
  • 標準エラー出力: $stderrまたはSTDERR
  • $stdin, $stdout, $stderrKernelで定義されている。
  • STDIN, STDOUT, STDERRObjectで定義されている。
  • これらは全てIOクラスのインスタンス。
  • よく使うメソッド

標準入力から入力するとカーソルの挙動がおかしい

少なくともmacでは、標準入力から入力すると、バックスペース(delete)の挙動がおかしい。 例えば「あいう」のあとdeleteキーを2回押しても、カーソルは「う」の位置で、表示は「あい」になる。 返された文字列は「あ」で正しい。

この問題を解決するには、Readlineモジュールを使うのが簡単。 複数行対応のメソッドはないが、以下のようにすれば複数行対応可能。 入力終了はCtrl + Dで同じ(この場合Readline#readlineはnilを返す)。 Emacsキーバインドも使える。

note = ""
while (buf = Readline.readline) != nil
  note += buf + "\n"
end

なお、上のコードはwhile buf = Readline.readlineでもOKですが、 ==の間違いと誤解されるので、あえてnilと比較するようにしました。

端末にカラー出力

AWS

外部サイト

逆引きマニュアル