忘備録

日々の調べ物をまとめる。アウトプットする。基本自分用。

『初めてのRuby』

0 3 * * 1 /root/bin/clamdscan.sh > /dev/null 2>&1

http://mktktmr.hatenablog.jp/entry/

初めてのRuby

を読み始めたので、ちょっとずつ、要点をメモってく。 自分がJava屋出身なので、Javaとの違いとか書いてくかも(書くとは言っていない)

読み始めて気付いたこと

この記事を書いてる時点(2016/06/08)でこの書籍はまだ初版なのですが、これからRubyを始める人にとっては情報が古くてしんどいかも。

というのも、この書籍がカバーしているRubyのバージョンは1.9までで、現時点での最新の安定版は2.2.5。

著者はバージョン2.0で大きな変化があるはずと予言(実際にそうなったかは、今後調べる)していて、もし本当なら、この書籍を通して勉強して大丈夫なのかと不安に駆られる。

まあ、Rubyの歴史を勉強するというつもりで読めば良いかも 笑

1章

バージョン体系

バージョンの書式

(Major).(Minor).(Teeny)(Patch Level)
  • Minor
    • 偶数のバージョンが安定版
      ※ 1.9は例外で1.9.0が開発版で1.9.1以降は安定版
  • Path Level
    • 1.9以降に導入された形式でバグ修正のカウント数
    • 非互換性は含まれない
  • Teeny
    • ライブラリへの新機能の追加やAPIのdeprecateが含まれる場合がある
    • 互換性に対する注意が必要

例)バージョンの確認

ruby -v
ruby 2.0.0p481

構成

言語本体

変数やクラス定義、メソッド定義、制御構造などを含む言語本体の仕様。
この仕様に基づいて、プログラムやライブラリを解釈、実行することを処理系と呼ぶ。

組み込みライブラリ

入出力や文字列、配列など、処理系に組み込まれている基本的なライブラリで、明示的にライブラリをロードしなくても利用できる。
また、以下のように細分化できる。

  • 組み込み定数
  • 組み込み変数
  • 組み込み関数
  • 組み込みクラス

標準添付ライブラリ

処理系に付属して配布される外部ライブラリで、明示的にライブラリをロードしないと利用できない。

RubyGems

Ruby1.9から標準添付ライブラリに入り、デファクトスタンダードとなっているRubyのパッケージ管理システム。

Rubyの処理系実装

MRI (Matz's Ruby Implementation)

オリジナルのRuby実装。C言語で書かれているためCRubyとも呼ばれる。

JRuby

MRIJavaで書き直して実装されていて、JVM上で動作する。

IronRuby

.NET Dynamic Language Runtime上で動作する実装。

実行モデル

MRIの場合、インタプリタ
1.9以降は、

解析 => バイトコード変換 => 実行  

という流れ。
解析フェーズでは構文上の妥当性のみ検証されるので、存在しないクラスの継承などは実行時にエラーとなる。

ガベージコレクション

が、実装されているので、プログラマがメモリ管理をする必要はない。

実行時ロード

外部ライブラリをロードする際は実行時にロードされる

main.rb

require 'exlib.rb'

# メイン処理

上記ソースの場合、

  1. main.rbの解析(この時点でexlib.rbの解析は行われない)
  2. main.rbの実行
    2.1. main.rbの実行開始
    2.2. exlib.rbの解析(この時点でまだメイン処理は実行されていない)
    2.3. exlib.rbの実行
    2.4. main.rbの実行に戻る(メイン処理の実行)

という順番で処理が行われる。

文法と機能

式の区切り

入出力

制御式

ブロック付きメソッド

イテレータ
リソース管理
コールバック

OOP

クラス
特異メソッド
演算子ポリモフィズム

2

章 配列とハッシュ

配列

参照

  • まず知っておくべきことは、添字参照はArray#[]メソッドのシンタックスシュガーであること
    • array[0] => array.
  • 範囲外の要素を参照するとnilを返す
array = [0, 1, 2, 3]
puts array[4] # nil. JavaのListクラスの場合、範囲外の要素を参照しようとすると例外(IndexOutOfBoundsException)が発生する
  • 負の添字
    末尾から逆順に要素を取得する
array = [0, 1, 2, 3]
puts array[-1] # 3. array[array.length-1]と等価
puts array[-2] # 2
  • 位置と長さを指定して取得
array = [0, 1, 2, 3]
puts array[2, 2] # [2, 3]. 2番目の要素から2個の要素を取得.
puts array[2, 100] # [2, 100]. 範囲内の要素が含まれていればそれだけを返す
puts array[100, 1] # nil. 範囲内の要素が含まれていなければ、nilを返す
puts array[-3, 3] # [1, 2, 3]. 位置の指定には負の値が利用できる(長さには使えない)
  • 範囲の指定
array = [0, 1, 2, 3]
puts array[1..3] # [1, 2, 3]
puts array[1...3] # [1, 2]. 末端を含まない範囲指定には「...」を利用する
puts array[-4..-3] # [0, 1]. 負の値を範囲の指定に利用できる
puts array[-4..1] # [0, 1]

代入

  • 添字代入はArray#[]=メソッドのシンタックスシュガー
  • 添字代入のいろいろ
array = [1,2]
array[0] = 3 # [3, 2]
array[4] = 4 # [3, 2, nil, nil, 4]. 範囲外を指定して代入した場合、配列が自動的に拡張され、空白の部分にはnilが挿入される
array[0, 3] = 'a', 'b', 'c' # ["a", "b", "c", nil, 4]. 位置と長さによる指定で代入もできる
array[0, 3] = 'a', 'b', 'c', 'd' # ["a", "b", "c", "d", nil, 4]. 左辺で指定した要素数よりも右辺の式が多い場合、配列が拡張されて代入される
array[1..2] = 1, 2 # ["a", 1, 2, "d", nil, 4]
array[0, 2] = '?' # ["?", 2, "d", nil, 4]. #左辺で指定した要素数よりも、右辺の式が少ない場合、配列が詰められて代入される
array[0..2] = 'A' # ["A", nil, 4]
array[-1] = 'Z' # ["A", nil, "Z"]

rbenvでRubyのバージョンを管理する

rbenvを利用して、Rubyのバージョンを切り替える方法のメモ。

当方の環境

Homebrewでrbenvをインストール

$ ruby -v
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14] # プリセットのrubyバージョン
# Homebrewの更新
$ brew update
Updated Homebrew from 9185c50 to dde20cd.
==> Migrating Homebrew to v0.9.9
remote: Counting objects: 271, done.
remote: Compressing objects: 100% (219/219), done.
remote: Total 271 (delta 142), reused 124 (delta 38), pack-reused 0
Receiving objects: 100% (271/271), 445.51 KiB | 413.00 KiB/s, done.
Resolving deltas: 100% (142/142), completed with 140 local objects.
From https://github.com/Homebrew/brew
 + dde20cd...2ca6dbb master     -> origin/master  (forced update)
HEAD is now at 2ca6dbb brew.rb: Don’t ask `xcrun` for output if no CLT is installed (#334)
==> Homebrew has enabled anonymous aggregate user behaviour analytics
Read the analytics documentation (and how to opt-out) here:
  https://git.io/brew-analytics
==> Tapping homebrew/core
Cloning into '/usr/local/Library/Taps/homebrew/homebrew-core'...
remote: Counting objects: 3710, done.
remote: Compressing objects: 100% (3593/3593), done.
remote: Total 3710 (delta 13), reused 2375 (delta 8), pack-reused 0
Receiving objects: 100% (3710/3710), 2.88 MiB | 224.00 KiB/s, done.
Resolving deltas: 100% (13/13), done.
Checking connectivity... done.
Tapped 3588 formulae (3,736 files, 9.0M)
==> Cleaning up /Library/Caches/Homebrew...
Removing: /Library/Caches/Homebrew/binutils-2.25.1.yosemite.bottle.tar.gz... (44.2M)
Removing: /Library/Caches/Homebrew/coreutils-8.24.yosemite.bottle.1.tar.gz... (3.3M)
Removing: /Library/Caches/Homebrew/nmap-7.00.yosemite.bottle.tar.gz... (6M)
Removing: /Library/Caches/Homebrew/openssl-1.0.2d_1.yosemite.bottle.tar.gz... (3.6M)
==> Migrating /Library/Caches/Homebrew to /Users/makoto/Library/Caches/Homebrew.
==> Deleting /Library/Caches/Homebrew...
Already up-to-date.
# rbenvのインストール
$ brew install rbenv
==> Installing dependencies for rbenv: autoconf, pkg-config, openssl, rub
==> Installing rbenv dependency: autoconf
==> Downloading https://homebrew.bintray.com/bottles/autoconf-2.69.yosemite.bott
######################################################################## 100.0%
==> Pouring autoconf-2.69.yosemite.bottle.4.tar.gz
==> Caveats
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/autoconf
==> Summary
🍺  /usr/local/Cellar/autoconf/2.69: 70 files, 3.0M
==> Installing rbenv dependency: pkg-config
==> Downloading https://homebrew.bintray.com/bottles/pkg-config-0.29.1.yosemite.
######################################################################## 100.0%
==> Pouring pkg-config-0.29.1.yosemite.bottle.tar.gz
🍺  /usr/local/Cellar/pkg-config/0.29.1: 10 files, 627.2K
==> Installing rbenv dependency: openssl
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2h_1.yosemite.b
######################################################################## 100.0%
==> Pouring openssl-1.0.2h_1.yosemite.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl/bin/c_rehash

This formula is keg-only, which means it was not symlinked into /usr/local.

Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you’ll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include

==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2h_1: 1,691 files, 12.0M
==> Installing rbenv dependency: ruby-build
==> Downloading https://github.com/rbenv/ruby-build/archive/v20160602.tar.gz
==> Downloading from https://codeload.github.com/rbenv/ruby-build/tar.gz/v201606
######################################################################## 100.0%
==> ./install.sh
🍺  /usr/local/Cellar/ruby-build/20160602: 282 files, 155.5K, built in 9 seconds
==> Installing rbenv
==> Downloading https://homebrew.bintray.com/bottles/rbenv-1.0.0.yosemite.bottle
######################################################################## 100.0%
==> Pouring rbenv-1.0.0.yosemite.bottle.tar.gz
==> Caveats
Rbenv stores data under ~/.rbenv by default. If you absolutely need to
store everything under Homebrew’s prefix, include this in your profile:
  export RBENV_ROOT=/usr/local/var/rbenv

To enable shims and autocompletion, run this and follow the instructions:
  rbenv init
==> Summary
🍺  /usr/local/Cellar/rbenv/1.0.0: 36 files, 61.9K

rbenvの使い方

# インストールできるバージョンの確認
$ rbenv install -l
Available versions:
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
  1.8.5-p52
  1.8.6-p110
  1.8.6-p111
  1.8.6-p114
  1.8.6-p230
  1.8.6-p286
  1.8.6-p287
  1.8.6-p36
  1.8.6-p368
  1.8.6-p369
  1.8.6-p383
  1.8.6-p388
  1.8.6-p398
  1.8.6-p399
  1.8.6-p420
  1.8.6
  1.8.7-preview1
  1.8.7-preview2
  1.8.7-preview3
  1.8.7-preview4
  1.8.7-p160
  1.8.7-p17
  1.8.7-p173
  1.8.7-p174
  1.8.7-p22
  1.8.7-p248
  1.8.7-p249
  1.8.7-p299
  1.8.7-p301
  1.8.7-p302
  1.8.7-p330
  1.8.7-p334
  1.8.7-p352
  1.8.7-p357
  1.8.7-p358
  1.8.7-p370
  1.8.7-p371
  1.8.7-p373
  1.8.7-p374
  1.8.7-p375
  1.8.7-p71
  1.8.7-p72
  1.8.7
  1.9.0-0
  1.9.0-1
  1.9.0-2
  1.9.0-3
  1.9.0-4
  1.9.0-5
  1.9.1-preview1
  1.9.1-preview2
  1.9.1-rc1
  1.9.1-rc2
  1.9.1-p0
  1.9.1-p129
  1.9.1-p243
  1.9.1-p376
  1.9.1-p378
  1.9.1-p429
  1.9.1-p430
  1.9.1-p431
  1.9.2-preview1
  1.9.2-preview3
  1.9.2-rc1
  1.9.2-rc2
  1.9.2-p0
  1.9.2-p136
  1.9.2-p180
  1.9.2-p290
  1.9.2-p318
  1.9.2-p320
  1.9.2-p326
  1.9.2-p330
  1.9.3-dev
  1.9.3-preview1
  1.9.3-rc1
  1.9.3-p0
  1.9.3-p105
  1.9.3-p125
  1.9.3-p194
  1.9.3-p286
  1.9.3-p327
  1.9.3-p362
  1.9.3-p374
  1.9.3-p385
  1.9.3-p392
  1.9.3-p426
  1.9.3-p429
  1.9.3-p448
  1.9.3-p484
  1.9.3-p545
  1.9.3-p547
  1.9.3-p550
  1.9.3-p551
  2.0.0-dev
  2.0.0-preview1
  2.0.0-preview2
  2.0.0-rc1
  2.0.0-rc2
  2.0.0-p0
  2.0.0-p195
  2.0.0-p247
  2.0.0-p353
  2.0.0-p451
  2.0.0-p481
  2.0.0-p576
  2.0.0-p594
  2.0.0-p598
  2.0.0-p643
  2.0.0-p645
  2.0.0-p647
  2.0.0-p648
  2.1.0-dev
  2.1.0-preview1
  2.1.0-preview2
  2.1.0-rc1
  2.1.0
  2.1.1
  2.1.2
  2.1.3
  2.1.4
  2.1.5
  2.1.6
  2.1.7
  2.1.8
  2.1.9
  2.1.10
  2.2.0-dev
  2.2.0-preview1
  2.2.0-preview2
  2.2.0-rc1
  2.2.0
  2.2.1
  2.2.2
  2.2.3
  2.2.4
  2.2.5
  2.3.0-dev
  2.3.0-preview1
  2.3.0-preview2
  2.3.0
  2.3.1
  2.4.0-dev
  jruby-1.5.6
  jruby-1.6.3
  jruby-1.6.4
  jruby-1.6.5
  jruby-1.6.5.1
  jruby-1.6.6
  jruby-1.6.7
  jruby-1.6.7.2
  jruby-1.6.8
  jruby-1.7.0-preview1
  jruby-1.7.0-preview2
  jruby-1.7.0-rc1
  jruby-1.7.0-rc2
  jruby-1.7.0
  jruby-1.7.1
  jruby-1.7.2
  jruby-1.7.3
  jruby-1.7.4
  jruby-1.7.5
  jruby-1.7.6
  jruby-1.7.7
  jruby-1.7.8
  jruby-1.7.9
  jruby-1.7.10
  jruby-1.7.11
  jruby-1.7.12
  jruby-1.7.13
  jruby-1.7.14
  jruby-1.7.15
  jruby-1.7.16
  jruby-1.7.16.1
  jruby-1.7.16.2
  jruby-1.7.17
  jruby-1.7.18
  jruby-1.7.19
  jruby-1.7.20
  jruby-1.7.20.1
  jruby-1.7.21
  jruby-1.7.22
  jruby-1.7.23
  jruby-1.7.24
  jruby-1.7.25
  jruby-9.0.0.0.pre1
  jruby-9.0.0.0.pre2
  jruby-9.0.0.0.rc1
  jruby-9.0.0.0.rc2
  jruby-9.0.0.0
  jruby-9.0.1.0
  jruby-9.0.3.0
  jruby-9.0.4.0
  jruby-9.0.5.0
  jruby-9.1.0.0-dev
  jruby-9.1.0.0
  jruby-9.1.1.0
  jruby-9.1.2.0
  maglev-1.0.0
  maglev-1.1.0-dev
  maglev-2.0.0-dev
  mruby-dev
  mruby-1.0.0
  mruby-1.1.0
  mruby-1.2.0
  rbx-2.2.2
  rbx-2.2.3
  rbx-2.2.4
  rbx-2.2.5
  rbx-2.2.6
  rbx-2.2.7
  rbx-2.2.8
  rbx-2.2.9
  rbx-2.2.10
  rbx-2.3.0
  rbx-2.4.0
  rbx-2.4.1
  rbx-2.5.0
  rbx-2.5.1
  rbx-2.5.2
  rbx-2.5.3
  rbx-2.5.4
  rbx-2.5.5
  rbx-2.5.6
  rbx-2.5.7
  rbx-2.5.8
  rbx-2.6
  rbx-2.7
  rbx-2.8
  rbx-2.9
  rbx-2.10
  rbx-2.11
  rbx-2.71828182
  rbx-3.0
  rbx-3.1
  rbx-3.2
  rbx-3.3
  rbx-3.4
  rbx-3.5
  rbx-3.6
  rbx-3.7
  rbx-3.8
  rbx-3.9
  rbx-3.10
  rbx-3.11
  rbx-3.12
  rbx-3.13
  rbx-3.14
  rbx-3.15
  rbx-3.16
  rbx-3.17
  rbx-3.18
  rbx-3.19
  rbx-3.20
  rbx-3.21
  rbx-3.22
  rbx-3.23
  rbx-3.24
  rbx-3.25
  rbx-3.26
  rbx-3.27
  rbx-3.28
  rbx-3.29
  rbx-3.30
  rbx-3.31
  rbx-3.32
  rbx-3.33
  ree-1.8.7-2011.03
  ree-1.8.7-2011.12
  ree-1.8.7-2012.01
  ree-1.8.7-2012.02
  topaz-dev
# 任意のバージョンをインストール
$ rbenv install 2.2.5
Downloading ruby-2.2.5.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.5.tar.bz2
Installing ruby-2.2.5...
Installed ruby-2.2.5 to /Users/makoto/.rbenv/versions/2.2.5
# 利用できるバージョンの確認
$ rbenv versions
* system (set by /Users/makoto/.rbenv/version)
  2.2.5
# 有効になっているバージョンの確認
$ rbenv version
system (set by /Users/makoto/.rbenv/version)
# 環境全体のバージョンを変更
$ rbenv global 2.2.5
# ディレクトリ固有のバージョン変更
$ rbenv local 2.2.5
# バージョン確認
$ rbenv version
2.2.5 (set by /Users/makoto/.rbenv/version)
# rubyコマンドでもバージョン確認
$ ruby -v
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14] # 。。。っ!!?

バージョンの切り替えが上手くいかなかった原因

~/.bash_profileに以下を追記する必要があった。

eval "$(rbenv init -)"

これをしないと、rbenvでインストールしたrubyのPATHが反映されない。

$ vi ~/.bash_profile # eval "$(rbenv init -)"を追記
$ source ~/.bash_profile # .bash_profileを読み込み、追記した設定を反映
# 改めてバージョンを確認
$ ruby -v
ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-darwin14]

参考サイト

rbenvでRubyのバージョンアップをする(for Mac) - Qiita

rbenv を利用した Ruby 環境の構築 | Developers.IO

rbenvでバージョンがうまく切り替わらなかった時にやったこと - Qiita