インストール
rbenvが良さそうです。
よく使うもの
文法
- クラス/メソッドの定義
- メソッド呼び出し
- メソッド名
?
,!
がメソッド名に使えます1。
case
他の言語ではswitch文に相当するもの。
-
case〜when(複数)〜else〜end
-
breakは不要(バグを引き起こしにくい)
-
whenはカンマ区切りで複数指定可能
-
比較には
===
演算子が使われる===
演算子はObjectで定義されていて、デフォルトは==
と同じ。Range, Regexpなどで上書きされている。
演算子式
- 多重代入
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
例外
- 文法: 制御構造
- 例外クラス: 組み込みライブラリ
- ArgumentError: 引数が不正(JavaにおけるIllegalArgumentException)
- RuntimeError: その他の例外(JavaにおけるRuntimeException)
呼び出し元で処理させたい場合は自前で例外クラスを作る、 それ以外は単にraiseを使ってRuntimeExceptionを投げるのでいいと思います。
数値
- 桁数取得
n.to_s.size
(正だと分かっている場合)n.abs.to_s.size
Math.log10(n.abs)
乱数
Kernel#randを使う。
rand # 0〜1までの実数
rand(2) # 0 or 1
rand(100) # 0〜99
初回呼び出し時にはKernel#srandを使って、 乱数の種を初期化する。
文字列
- class String
- 分割: String#split
- 改行コード(LF)で分割:
str.split("\n")
- 改行コード(LF)で分割:
- 数値に変換
- 安全でない: to_i (“foo”.to_i => 0となってしまう)
- 安全: Integer(str)
- 変換できないときはArgumentErrorが投げられる
- 文字列の検索: String#index
- 文字列が含まれている(Javaだとcontains): String#include?
start_with?(*prefixes) -> bool
: 先頭がprefixesのいずれかのときtrueend_with?(*strs) -> bool
: 末尾がstrsのいずれかのときtrue- 最初と最後の1文字を削除:
str = str.slice(1..-2)
- フォーマット: String#%
- 例:
"%4d" % i
- 例:
正規表現
- 正規表現リテラル
- %記法もある。
- 例:
%r|...|
- 例2:
%r(...)
カッコ((
,[
,{
,<
)は閉じカッコに対応
- Regexp
- MatchData
- マッチした文字列だけ取り出す場合
- 1つだけ: Regexp#match または String#match
- 例:
"abcdef".match(/([c-e]+)/)[1] => "cde"
- 例:
- 配列で取得: String#scan
- 1つだけ: Regexp#match または String#match
- マッチした文字列を置き換える場合はString#gsubがよい。
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を挙げているので、利用機会は多いです。
- よく使うメソッド
- String#encode
- String#force_encoding
- 破壊的メソッドのため、推測に使用する場合はObject#dupを使っておく。
- String#valid_encoding?
エンコーディングのリスト
以下のコマンドで取得可能。
ruby -e "puts Encoding.list" | sort
環境変数
ENV['FOO']
文字列はfreezeされている(変更不可)
Array
- Arrayクラス
- 記法
- 追加: Array#push
- 含まれているか: Enumerable#include?
- 評価したものを返す: Enumerable#map
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)
- 書式はTime#strftimeにまとまっている。
- 日本語の曜日:
%w(日 月 火 水 木 金 土)[time.wday]
(日本語曜日入り日付フォーマットを1行で書く - Qiitaより)%w()
は配列を表す記法です(%記法)。
- 解析
- Time#parse
require 'time'
しないと使えないのに注意。
- より柔軟な表現が欲しい場合はChronicを使う。
- Time#parse
Enumerable
- Enumerable
- mapでindexも使いたい:
.map.with_index
を使う(Rubyのmapやselectでもeach_with_indexみたいにindexを使いたいときはEnumerator#with_index - Qiita)。
ネット
URL/URI
- URI
- URI#encode_www_form
- Hashなどからクエリ文字列を作成するにはこちら。
- URI#encode_www_form
- URI::HTTP
- schemaなどのコンポーネントから作成する場合はこちら。
HTTP
- 簡易取得: open-uri
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
以下のように使います。 オブジェクトは以下のようになります。
- HTML: Nokogiri::HTML::Document
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
パス関連
- スクリプトのパス:
__dir__
- Ruby 2.0から使用可能です。
- Kernel#dirで定義されています。
- Pathname
- ドキュメント
- 拡張子を取得: Pathname#extname
JSON
- 準備:
require 'json'
- JSONファイルの読み込み:
JSON.parse(str)
JSON.parse(str, {:symbolize_names => true})
とすると、文字列をシンボルにしてくれる。
引数
テスト
入出力
- 標準入力:
$stdin
またはSTDIN
- 標準出力:
$stdout
またはSTDOUT
- 標準エラー出力:
$stderr
またはSTDERR
$stdin
,$stdout
,$stderr
はKernelで定義されている。STDIN
,STDOUT
,STDERR
はObjectで定義されている。- これらは全てIOクラスのインスタンス。
- よく使うメソッド
- 1行読み込み: IO#readline
- 1行ごと取得してブロック実行: IO#each_line
- 全て読み込んで配列として取得
標準入力から入力するとカーソルの挙動がおかしい
少なくとも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と比較するようにしました。
端末にカラー出力
- colorizeを使う。
AWS
外部サイト
- Rubyコーディング規約
- GitHub Styleguide を訳してみた(Ruby編) - Qiita
- styleguide/ruby.ja.md at master · cookpad/styleguide