忘備録

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

『初めての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"]