概要
Railsの5.0系が正式リリースされて早3ヶ月が経過しました。
そろそろ触らないとまずいと思い、Rubyの復習からさくっとやりました。
(最近は、Pythonの事ばかり考えていたので、頭の整理もしたかった。)
内容に関しては、主要機能のみをさくっとまとめた感じです。
ターミナル操作
- irb
- Intaractive Ruby
- ターミナルでインタラクティブにコマンドを確認できる。
- ri
-
ri Array
などで命令やオブジェクトのドキュメントを確認できる。
-
出力系の命令
- print
- コンソール出力
- puts
- 改行付きコンソール出力
- p
- デバッグ用コンソール出力
- 行末のセミコロンは原則なし
- コメント
- #
- =begin~=end
変数と定数
- 変数
- 英語小文字 or _(最初の文字)
msg = 'Hello'
- 定数
- 英語大文字(最初の文字)
- 再代入しても、警告は出るが、値は変わってしまう。
Rubyのオブジェクトの概念
オブジェクトの理解
- 全ての値がオブジェクトである。
- 'hello world'や1.1など
- オブジェクトとは何か
- 便利な命令をたくさん持ったデータ型
'hello world'.length
- オブジェクトが用意している命令をメソッドと呼ぶ。
- 便利な命令をたくさん持ったデータ型
-
どのメソッドが使えるかは、その値がどのオブジェクトに属しているかで変わる。
- オブジェクトの種類の事をクラスと呼ぶ。
- String Class
- Float Class
- Rubyではクラスを上手く使う事でいいプログラムが書ける。
- オブジェクトの種類の事をクラスと呼ぶ。
1.1や'hello world'の様な実際の値をインスタンスと呼ぶ。
オブジェクトは便利な命令をたくさん持ったデータ型
-
インスタンスは、クラスから生成された実際の値。
- 型を必ず持つ
- 型 = クラス
クラスの情報取得メソッド
- クラスの確認
<instance>.class
- インスタンスが持つメソッドの確認
<instance>.methods
- Fixnumクラス
- Floatクラス
<instance>.round
<instance>.floor
<instance>.ceil
文字列オブジェクト
- ""
- 特殊文字が使える
- 式展開が可能
- ''
- 特殊文字が使えない
- 式展開が不可能
- #{}
- 文字列中でRuby式が評価される。
- +
- 文字列を連結できる。
- *
- 文字列を繰り返す。
破壊的メソッドと真偽値メソッド
- !が付くメソッド
- 破壊的メソッド
- !なしは単純に値を返すだけ
- !があるものは、値を返し、元の値も変更する。
- ただし、感嘆符付きのメソッドが必ずしも破壊的とは限らない。
-
upcase!
orupcase
- 破壊的メソッド
- ?が付くメソッド
- 真偽値を返すメソッド
- ```.empty?
- ```.include?()
配列オブジェクト
colors = [
'red',
'blue',
'yellow'
]
p colors[0] # "red"
p colors[-1] # "yellow"
p colors[0..2] # ["red", "blue", "yellow"]
p colors[0...2] # ["red", "blue"]
p colors[5] # nil
colors[0] = 'pink'
colors[1..2] = ['white', 'black']
colors.push('gold')
colors << 'silver'
p colors # ["pink", "white", "black", "gold", "silver"]
p colors.size # 5
p colors.sort # ["black", "gold", "pink", "silver", "white"]
- 添え字の-値
- -1で1番後ろの要素
- -2で後ろから2番目の要素
-
添え字の範囲指定
- ..で添え字から添え字まで
- ...で添え字から添え字の1つ前の添え字まで
- 要素がない添え字を指定
- nilを返す
- 要素の書き換え
- 添え字を指定して代入
- 要素の範囲指定入れ替え
- 添え字を範囲で指定して、配列を代入
- 要素を末尾に追加
<instance>.push(<値>)
<instance> << <値>
- 配列の要素数を返す
<instance>.size
- 配列の順序を並び替える
<instance>.sort
ハッシュオブジェクト
- 辞書型
- key & value
# アローで表現する
scores = {
"fujimoto" => 200,
"horio" => 400
}
# シンボル & アローで表現する
scores = {
:fujimoto => 200,
:horio => 400
}
# シンボル & ショートハンドで表現する
scores = {
fujimoto: 200,
horio: 400
}
p scores[:fujimoto] # 200
scores[:horio] = 100
p scores # {:fujimoto=>200, :horio=>100}
p scores.size # 2
p scores.keys # [:fujimoto, :horio]
p scores.values # [200, 100]
p scores.has_key?(:fujimoto) # true
シンボルオブジェクト
- 文字列の様なもの(識別子として利用する)
-
高速な識別子という認識
- ハッシュクラスを作成する際に利用する事が多い
オブジェクトの変換
-
<instance>.to_i
- 数値に変換(integer)
-
<instance>.to_f
- 小数値に変換(float)
-
<instance>.to_s
- 文字列に変換(string)
-
<instance>.to_a
- 配列に変換(array)
- オブジェクトを配列に変換できる
[[:fujimoto, 200], [:horio, 300]]
-
<instance>.to_h
- ハッシュに変換(hash)
便利な%記法
- % or %Q
- 文字列を表現
- ダブルクォーテーション
p %(hello) # "hello"
- %q
- 文字列を表現
- シングルクォーテーション
p %q(hello) # 'hello'
- %W
- 配列を表現
- スペース区切り
- 式展開あり
p %W(red blue) # ["red", "blue"]
- 配列を表現
- %w
- 配列を表現
- スペース区切り
- 式展開なし
- 配列を表現
- %r
- 正規表現を表現
-
%s
- シンボルを表現
クォーテーションを書かなくてもよくなる。
文字列中でのクォーテションが見やすくなる。
書式付きで値を埋め込む
- %s
- 文字列
- %d
- 数値
- %f 小数値
p "name: %s" % 'fujimoto' # "name: fujimoto"
p "id: %05d & rate: %5.2f" % [3, 83.2] # "id: 00003 & rate: 83.20"
- printf
- 書式付き文字列をコンソールに表示する
- ```printf("name: %s", "fujimoto")
- sprintf
- 書式付き文字列を返す
- ```p sprintf("name: %s", "fujimoto")
条件分岐
puts "テストの点数を入力して下さい。"
score = gets.to_i
if score > 80 then
puts "great!"
elsif score > 60 then
puts "better"
else
puts "soso!"
end
- gets
- ターミナルでインタラクティブに入力を求める。
- 条件文のthenは省略可能
- 最後はendで終わる
-
論理演算子
- &&(AND)
- ||(OR)
- !(NOT)
1行で書く
p "great" if score >= 20
- 三項演算子で書く
puts score > 50 ? 'OK' : 'NG'
caseの条件分岐
signal = gets.chomp
case signal
when 'red'
p 'stop'
when 'green', "blue"
p 'go'
when 'yellow'
p 'caution'
else
p 'wrong'
end
- case-when-else-endで記述する。
-
<instance>.chomp
- 末尾の改行を削除する
制御構造での繰り返し
while
i = 0
while i < 10 do
p "#{i}: hello"
i += 1
end
for
- 配列・ハッシュ・範囲オブジェクト分だけループを回す際に利用する。
colors = [
'red',
'blue'
]
scores = {
fujimoto: 200,
horio: 300
}
for color in colors do
p color
end
for name, score in scores do
p "#{name}: #{score}"
end
- do-endの部分は{}で表現も可能
- doは省略可能。
イテレータでの繰り返し
each
- for文は内部的にeachが使われている為、書き換え可能。
colors = [
'red',
'blue'
]
scores = {
fujimoto: 200,
horio: 300
}
colors.each do |color|
p color
end
scores.each do |name, score|
p "#{name}: #{score}"
end
- whileと同じ様に1行で表現する場合は、do-endを波かっこで表現も可能。
- doの省略は不可。
times
- 回数が決まっている際に利用する。
- 数字クラスのメソッド
10.times do |i|
puts "#{i}: hello"
end
10.times { |i|
puts "#{i}: hellohello}"
}
- doの後ろにブロックパラメーターを準備できる。
|i|
- doは省略可能。
無限ループ
loop do-end
繰り返しで使える命令
- ループ終了
- break
- ループスキップ
- skip
メソッド
- 本来はクラスに定義するもの
- グローバルに直接定義する事も可能
- privateとなる。
def sayHello
p "hello"
end
sayHello # hello
- def-endで囲う
- ()で引数を渡す事も可能
- =で初期化も可能
- 実行側の()は省略可能。
- returnを使わなくても、最後の値を返す様になる。
クラス
- クラスは大文字から始まる
- インスタンス化
tom = User.new
- イニシャライズ
def initialize()-end
- インスタンス変数
@variable
- クラス内部のどこからでも参照可能
- メソッド内でのみ定義可能
アクセサ
- インスタンス変数には直接アクセスできない
- すべてprivate
-
getter/setterの為のショートハンド
- アクセサ
-
attr_accessor <Symbol>
- setterとgetterを作ってくれる
-
- getterのみ定義
attr_reader <Symbol>
- アクセサ
-
self
- レシーバを指す
- クラスメソッド内で利用可能
- レシーバである事に注意。
- attr_accessorやattr_readerを付与していれば呼び出せる
- レシーバである事に注意。
- selfは曖昧な表現にならない限り省略可能である。
-
レシーバ
- メソッドを受け取っている(インスタンス)の事。
class User
attr_reader :name
def initialize(name="noName")
@name = name
end
def sayHi
# @<var>でインスタンス変数にアクセス
# return "Hi, #{@name}"
# selfでレシーバにアクセス
# return "Hi, #{self.name}"
# selfは曖昧にならない限り省略可能
return "Hi, #{name}"
end
end
クラス変数・クラスメソッド・クラス定数
- クラス変数は@@で定義する
- クラスメソッドはメソッド名にselfをつける
- ```Class.で呼び出し可能
- 関数名の先頭にselfをつけると、クラスメソッドの作成となる。
- クラス定数は全て大文字で宣言する
-
Class::<CONST>
で呼び出し可能
-
class User
attr_reader :name
# クラス変数を定義する。
# クラス変数は直接呼び出せない
@@count = 0
# 定数を宣言する。
VERSION = 1.1
def initialize(name="noName")
@name = name
# インスタンス化される度にクラス変数を1増加する。
@@count += 1
end
def sayHi
return "Hi, #{name}"
end
# クラスメソッドを定義する。
def self.info
p "hi, i am UserClass, #{@@count} Version: #{VERSION}"
end
end
# クラスメソッドの呼び出し
User.info
# クラス定数の呼び出し
p User::VERSION
クラスの継承
class AdminUser < User
def sayHello
puts "Hello from #{name}"
end
end
tom = AdminUser.new("TOM")
p tom.sayHi
tom.sayHello
- <で継承でできる
- オーバーライド可能
メソッドのアクセス権
- 原則はpublic
- initializeとクラスの外に書いたメソッドはprivateになる。
- privateはクラスの中で定義して、クラスのメソッド内部で利用する。
- privateメソッドはself指定なしで呼び出す。
- privateメソッドはselfが使えない為
- Rubyのprivateメソッドはオーバーライドが可能である。
- privateメソッドはself指定なしで呼び出す。
class User
attr_reader :name
def initialize(name="noName")
@name = name
end
private def sayPrivate
puts "private"
end
def sayHi
sayPrivate
p "Hi, #{@name}"
end
end
class AdminUser < User
def sayHello
sayPrivate
puts "Hello from #{name}"
end
end
tom = User.new("TOM")
tom.sayHi
モジュール
- 継承不可
- インスタンス不可
- 用途2つ
- 名前空間を作成する。
- MIX-INを提供する。
- モジュールの1文字目は大文字
- モジュール変数 = 定数
- 普通の定数と同じ様に呼び出す。
- モジュール関数を作成できる
<ModuleName>.<method>
def self.<method> - end
# module
# クラス・メソッドOK
# インスタンス化できない・継承できない
# 用途 -> 名前空間
module Movie
VERSION = 1.1
def self.encode
puts "encoding"
end
def self.export
puts "export"
end
end
Movie.export
p Movie::VERSION
Mix-In
- モジュールの2つ目の役割
- 用途の違うクラスに共通の機能を付与する
- インスタンスメソッドとして定義する。
- 他のクラスのインスタンスに埋め込む事ができる。
- include命令を利用して、MIX-INを行う。
# デバッグ機能を各クラスに追加したい
module Debug
def info
puts "#{self.class} debug info..."
end
end
class Player
include Debug
end
class Monster
include Debug
end
player = Player.new
player.info
monaster = Monster.new
monaster.info
例外
- begin-rescue-endでtry-catch
- ensureで成功でもエラーでも行う処理を記述できる
- raiseで独自のエラークラスを引数に取り、エラーを発生させる事ができる。
- 独自エラークラスは、StandardErrorクラスを継承する事
class MyError < StandardError
end
x = gets.to_i
begin
if x == 3
raise MyError
end
p 100 / x
rescue MyError
puts "this is myError"
rescue => ex
p ex.message
p ex.class
p "stopeed"
ensure
p "--end--"
end
まとめ
やっぱりRubyの文法は好きです。
(GitHub社が好きな理由がよく分かる。)
次回はRails5.0で簡単アプリでも作りたいと思います。