Railsチュートリアル(第4版)の個人メモ
気になった部分、忘れそうな部分を記述。
- Ruby 2.6.1
- Rails 5.1.6
4章ではRailsで使うRubyの基礎について学習。
4章 Rails風味のRuby
Viewでの処理をシンプル、かつDRYにするために、
Railsでは「ヘルパー」として自作の関数を指定できる。(カスタムヘルパー)
4章の中ではRailsに関係してRubyの以下要素にふれる。
モジュール、メソッド定義、任意のメソッド引数、コメント、ローカル変数の割り当て、論理値 (boolean)、制御フロー、文字列の結合、戻り値
4.1
4.1.1 カスタムヘルパー
カスタムヘルパー
関数のようなもの。下記で定義。
app/helpers/application_helper.rb
4.2 文字列とメソッド
以下、Railsコンソールを主に使用して学習。
Railsコンソールはirb(Interactive Ruby)の拡張であるので、irbの設定を先にしておく。
4.2.2 文字列
文字列リテラル
>> puts "foo"
foo
=> nil
putsするとfooが出力され、 戻り値としてnil が返る。
putsは行末に ¥n
改行を含むので、
printで改行を含まず表示する。
ダブルクォート、シングルクォート
'
では式展開 #{foobar}
しない
4.2.3 オブジェクトとメッセージ受け渡し
Rubyでは文字列もnilも、全部オブジェクト。
オブジェクトはメッセージに応答する。
>> "foobar".length
=> 6
"foobar"
というオブジェクトは length
メッセージに応答。
このメッセージは メソッド
という。
nil
Rubyではオブジェクトそのものの論理値がfalseになるのは、falseかnilのみ。
オブジェクトを論理値に変換するときは!!
(バンバン)する。二重否定。
>> !!0 # true
0もnilではないのでtrue。
このundefinedとかnullとかNaNとか色々無いのはわかりやすいかもしれない。
nilというオブジェクトは empty?
メソッドは持たないが、
>> nil.empty?
# NoMethodError: undefined method `empty?' for nil:NilClass
to_s
で文字列に変換すればいい。
(ただし、nil?でも判定できる)
>> nil.to_s # ""
>> nil.to_s.empty? # true
>> nil.nil? # true
後続if
英語のようにifを後ろに持っていき、処理をワンライナーにできる
>> puts "x is not empty" if !x.empty?
!
はやはり否定。 if !
は unless
でも可
4.2.4 メソッドの定義
メソッド
引数を省略するときカッコも省略可能
def foobar(hoge = '')
end
p foobar #カッコも省略
暗黙の戻り値
def string_message(str = '')
return "It's an empty string!" if str.empty?
"The string is nonempty."
end
p string_message('noempty') # returnが無いけど3行目が返る。
4.2.5
モジュール
module ApplicationHelper
def full_title(page_title = '')
〜省略〜
end
end
module
は def
で定義したメソッドをまとめるもので、include
(mixed in) で呼び出す。
素のRubyではincludeで呼び出すが、Railsではincludeされるように組んであるのでノータッチ。
4.3 他のデータ構造
文字列、論理値(bool)以外
4.3.1 配列と範囲演算子
split
文字列を配列に。引数でデリミタの指定もできる
>> "foo bar baz".split # ["foo", "bar", "baz"]
>> "fooxbarxbaz".split('x') # ["foo", "bar", "baz"]
配列
- 配列の書き方、指定
ゼロオリジン。
>> a = [42, 8, 17]
>> a[0] # 42
指定の仕方
>> a.first
>> a.second
>> a.last == a[-1] # true
- 追加(push)
push(値)
、<< 値
(複数可 << 値 << 値 ...
)
%wを使っても文字列の配列に変換できる
>> %w[foo bar baz quux] # ["foo", "bar", "baz", "quux"]
- 連結(join)
join(デリミタ)
デリミタなしで単純に連結
範囲
>> a = (0..9).to_a # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 配列の取り出しなどにも
>> a[0..2] # [0, 1, 2]
# 3番目から最後、を明示的に
>> a[2..-1] == a[2..(a.length-1)] # true
# 後ろから7番目
>> a[-7]
4.3.2 ブロック
Rubyの慣例では
一行: 波括弧を使用 { }
複数行: do..end記法を使用
ブロックは、クロージャになっているとのこと。スコープに気をつける。
# ブロック
p (1..5).each {|i| puts 2 * i}
# 複数行のブロック
p (1..5).each do |number|
puts 2 * number
puts '--'
end
ブロック内で宣言した引数に対してメソッドを当てる場合、アンパサンド( &
) で省略する記法が使える。(symbol-to-proc)
>> %w[A B C].map { |char| char.downcase }
>> %w[A B C].map(&:downcase)
もともとRails独自の記法だったものが、Rubyのコア機能として採用されたんだとか。おもしろい。
演習 ランダムに文字生成
使える文字を配列に並べて、シャッフルして、必要文字数分取り出し、となっていたが、
一応重複も許すように作成し直してみた
# 演習3 ランダムで8文字生成
def random_subdomain(char_num = 0)
base_strings = [('0'..'9'), ('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
gen_word = []
char_num.times {
gen_word.push(base_strings.sample)
}
gen_word.join
end
puts random_subdomain(8)
4.3.3 ハッシュとシンボル
ハッシュ
PHPでいう連想配列は、ハッシュという
キーが数値になるものは、配列
ハッシュの並び順について、Ruby1.9までは保証していなかったが、今は定義やpushした順で変わらない。
注意として、空のハッシュの定義は hoge = { ... }
波括弧
シンボル
:hogepiyo
これがシンボル
user["name"]
文字列型のように
user[:name]
ハッシュのキーとして使える型。
ハッシュの定義には =>
が使われるが、
シンボルに限ってはコロンを後ろに持ってくればok
h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
h2 = { name: "Michael Hartl", email: "michael@example.com" }
h1 == h2 # true
each
を使った展開(PHPと比較)
foreach($flash as $key => $value){
echo "Key ${key} has value ${value}";
}
flash.each do |key, value|
puts "Key #{key.inspect} has value #{value.inspect}"
end
inspect
puts "hoge".inspect
で "hoge"
が表示。
よく使うので省略があり、 p "hoge"
でも同様の結果
PHPでいう var_dump()
のような感じか
4.3.3 CSS、再び
css呼び出しの部分
stylesheet_link_tag 'application', media: 'all',
'data-turbolinks-track': 'reload'
上記は大分省略されているので明示的に書くと以下の様になる。
stylesheet_link_tag('application', { media: 'all', 'data-turbolinks-track': 'reload' })
- 引数は丸括弧なしでも可。
- 引数の最後にハッシュが来る場合、波括弧を省略可
- Rubyはある程度自由に改行と空白を入れても、文脈で判断してくれる。
このため、改行で可読性を上げることも可
4.4 Rubyにおけるクラス
4.4.1 コンストラクタ
値は全てオブジェクト
Rubyで扱う値はすべてオブジェクト(何らかのクラスに属する)
"hogepiyo" == String.new("hogepiyo") # true
ダブルクォートで文字列を定義した際には、Stringクラスのインスタンスが生成されている。
なので、そのStringクラスに対応するメソッドが使えていた、ということ。
配列クラス( Array.new(["hoge", "piyo"])
)や、ハッシュクラス( Hash.new
)なども当然ある。
ハッシュクラスは Hash.new("default")
でキーが存在しない場合の初期値を定義できる。
指定なし Hash.new
ではnil
4.4.2 クラス継承
superclassメソッド
HogepiyoClass.superclass
で
継承元のクラスを調べられる。
Stringなら、
String < Object < BasicObject
でBasicObjectから順々に継承されている。
値すべてがオブジェクト、という意味がわかった。
class Word < String
def palindrome?
self == self.reverse
# 実は右のselfも省略できるので、
# self == reverse
# でもよい。
end
end
s = Word.new("level")
s.palindrome? # true
s.length # 5
# 適当にppとかで上記2点確認できる
4.4.5 ユーザークラス
インスタンス変数
@
から始まる変数。
メソッドの内側で定義したローカル変数のスコープはメソッド内で閉じるが、
インスタンス変数はクラス内の別メソッドでも使える変数。