気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

Ruby Silver試験前に見直すと幸せになれるメモ

silverにおいて勉強した内容をまとめておく。

主な特殊変数

特殊変数 説明
$_ gets() または readline() で最後に読み込んだ行
$! raise された例外オブジェクト
$` 正規表現にマッチした箇所より前の文字列
$' 正規表現にマッチした箇所より後ろの文字列
$~ 正規表現にマッチしたときの MatchData オブジェクト
$& 正規表現にマッチした箇所の文字列
$0 現在の Ruby スクリプト名。$PROGRAM_NAME と同じ

組み込み定数

組み込み定数 設定値
STDIN 標準入力
STDOUT 標準出力
STDERR 標準エラー出力
ENV 環境変数
ARGV Rubyスクリプトに与えられた引数
p ARGV[0] #Rubyスクリプトに与えられた引数
p ENV["path"} # 実行環境PCのPATH値

組み込み変数

$LOAD_PATHへ設定される値
1.Rubyインストールディレクトリ
2.ruby実行ディレクトリ

$LOAD_PATHは組み込み定数ではない。

rubyのローカル変数のスコープ

ローカル変数はclass, module, defの壁を超えられない。

outer = 123

def hoge
  puts outer
end

hoge()
#=> NameError: undefined local variable or method `outer' for main:Object

では、外部変数を参照したいときはどうするか

グローバル変数を使う??いやいや。。 ブロックを使うと良いらしい。

outer = 123

# トップレベルでdefine_methodを呼び出す
Kernel.send :define_method, :hoge do
  puts outer
end

hoge() #=> 123

ブロックは外側で宣言されたローカル変数を参照・変更できる。

インスタンス変数

継承で共有されない、インスタンス内で完結。
クラススコープに定義するクラスインスタンス変数とメソッド内に定義するインスタンス変数の2つが存在する。

class Test
    def initialize (value)
        @v1 = value
    end
    def method1
           @v1 
       end
end

Test.new(1).method1 #=> 1

rubyのクラス変数のスコープ

クラス変数は定義クラスとそのクラスを継承したサブクラスで
定義したメソッド内で参照、代入が可能。

条件分岐

変数宣言とif式の組み合わせの場合、判定結果に関わらず、変数自体は確保される

b = 3 if false
p b
=> nil

値の代入のみスキップされる

例外

begin
  p 1
rescue NoMethodError, ZeroDivisionError => e
  puts "Rescued in 'rescue NoMethodError, ZeroDivisionError => e'"
  p e
rescue StandardError => e # rescue => e でもOK
  puts "Rescued in 'rescue StandardError => e'"
  p e
else # rescue節が実行されない場合に実行される
  puts "There are no errors."
ensure # 必ず実行される
  puts "Ensure"
end

オブジェクト指向

Object
クラスで継承が可能、Kernelモジュールをincludeしている
スーパークラスBasic Object

Kernel
モジュールで継承できない

重要なメソッド
extend
モジュール内のインスタンスメソッドを特異クラスに追加。
モジュール内の特異メソッドはextendでは追加できない。

演算子

上書きできない演算子

分類 演算子
代入演算子(自己代入を含む) = +=
論理演算子 ! not && and || or
三項演算子 :?
:: ::
範囲演算子 .. ...

優先順位

主な演算子だけピックアップ

優先度 分類 演算子
高い 否定演算子 !
累乗 **
四則演算(高め) * / %
四則演算(低め) + -
シフト演算 << >>
論理積 &
論理和,排他的論理和 | ^
比較演算子(高め) > >= < <=
比較演算子(低め) <=> == === != =~ !~
and演算子 &&
or演算子 ||
範囲演算子 .. ...
条件演算子 ?:
自己代入演算子 =(+=, -= ... )
否定演算子(英字) not
低い and,or演算子(英字) and or

ざっくりだと以下を抑えておけば良いかな。
四則演算子 => 論理演算子 => 比較演算子 => and,or演算子(記号) => 条件演算子 => and,or演算子(英字)

|| はtrueの物を返却

p [1,2] || 5
=> [1,2]

配列

演算子(含まれる要素をすべて削除)

p [1,2,3,3,5,2,1] - [1,2,3]
=> [5]

each_index

[1,3,5,7,9].each_index{|n| puts n*2}
0
2
4
6
8

joinと「*」

「*」をjoinと置き換えても同様の動き

 [1,2,3] * ","
=> "1,2,3"

 [1,2,3] * "_"
=> "1_2_3"

zip

レシーバーを基準に処理される

[1,2,3].zip(["a","b","c"])
=> [[1, "a"], [2, "b"], [3, "c"]]

[1,2,3].zip([1,2,3,4])
=> [[1, 1], [2, 2], [3, 3]]

[1,2,3,4].zip([1,2,4])
=> [[1, 1], [2, 2], [3, 4], [4, nil]]

同じ動作をするメソッド

slice []
map collect
find detect
find_all select
delete_if reject!
has_key? include? key? member?

Hash

replace

部分置換でなく、全体置換

a = Hash["a",1,"b",2]
=> {"a"=>1, "b"=>2}
a.replace({"a" => 3})
=> {"a"=>3}
a
=> {"a"=>3}

同じ動作をするメソッド

merge! update
length size
has_value? value?
each each_pair

File

1 ファイルを開くモード(読み書きモード)

ファイル内容をどう読み書きしたいかで以下のいずれかに決まる。
r+ 読み書き共に先頭から
w+ 元のファイル内容を空にしてから書き込む場合
a+ 読み込みは先頭、書き込みは末尾

2 File::Statクラス

newメソッドのみクラスメソッド

3 getsメソッド

  • 一行読み込んで、読み込みに成功した時にはその文字列を返却
  • EOF に到達した時には nil を返却
  • 読み込んだ文字列を変数 $_ にセット
  • 引数に設定した文字列を区切り文字として用いる
# 太陽系の惑星のリストの内容を持つファイルを作成する
File.open("planets.txt", "w") do |f|
  f.puts(%w[Mercury Venus Earth Mars Jupiter Uranus Neptune])
end
f = File.open("planets.txt")
p f.gets(“Earth”)
=> "Mercury\nVenus\nEarth"
p f.gets(“Neptune”)
=> "\nMars\nJupiter\nUranus\nNeptune"
p f.gets
=> "\n"
p f.gets
=> nil

4 readline

getsとほぼ同じ、下記のみ異なる

  • EOF に到達した時には EOFError
f = File.new("oneline_file")
f.readline                      #=> "This is line one\n"
$_                              #=> "This is line one\n"
f.readline                      #=> EOFError

5 splitメソッド

p File.split("/home/john/bookmarks/")
=> ["/home/john", "bookmarks"]

・ファイルパスを挿入されるとディレクトリとファイルに分割
・分割した文字列の末尾の/を削除
・ファイルはパスの最後の文字列となる(上記の例だとbookmarks)
・ディレクトリとファイル文字列を含んだ配列を返却する

Ruby 2.1 の変更点について

多言語化

# 明示的に指定する場合は以下のスクリプトエンコーディングで指定。2.1からデフォ utf-8# encoding: utf-8

p "".encoding.name #=> "UTF-8"

# バイト単位でなく、文字列単位で扱うように変更になった
p "あいうえお"[0] #=> "あ"

p ?あ  #=> "あ"
p ?あ.ord #=> 12354
p 97.chr#=> "a" 
p 12354.chr("utf-8") #=> "あ"