目的
3章までで扱ったRailsにおいて重要となる
Rubyのさまざまな要素について理解する。
4.1.1 組み込みヘルパー
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
上記のソースではRubyの概念が4つある。
Railsの組み込み関数、カッコを使わないメソッド呼び出し、シンボル、ハッシュ
4.1.2 カスタムヘルパー
新しく作った組み込み関数をカスタムヘルパーと呼ぶ
例として下記コードでは問題点がある
問題点:タイトルが空だと | Ruby on Rails Tutorial Sample Appと先頭に余計な|がつく。
このページタイトルが正しく表示されない問題を解決するためにヘルパーを作成する。
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
<% provide(:title, "Home") %>
<h1>Sample App</h1>
<p>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</p>
・カスタムヘルパー作成方法
カスタムヘルパーをapplication_helper.rbに定義する
module ApplicationHelper
# ページごとの完全なタイトルを返す
def full_title(page_title = '')
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{page_title} | #{base_title}"
end
end
end
修正前
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
修正後
<title><%= full_title(yield(:title)) %></title>
と簡単に書けるようになった
4.2 文字列とメソッド
・式展開
Rubyはシングルクォート文字列の中では式展開を行わない。
'#{foo} bar' # シングルクォート内の文字列では式展開ができない
※シングルクォートは、入力した文字をエスケープせずに「そのまま」保持するときに便利
'\n' # 'バックスラッシュ n' をそのまま扱う
・式展開の結合
"#{first_name} #{last_name}"
・メソッド末尾の疑問符
empty?のようにrubyでは
メソッドがtrueまたはfalseという論理値(boolean)を返すことを、末尾の疑問符で示す
a
=> [42, 8, 17]
>> a.empty?
=> false
4.2.3メソッドの定義
・メソッド
Rubyのメソッドには暗黙の戻り値がある
これは、メソッド内で最後に評価された式の値が自動的に返されることを意味する
リターンが書かれていなくても値が返る
・ミックスイン(mixed in)
互いに関連する複数のメソッドをまとめる方法の1つ
includeメソッドを使ってモジュールを読み込むことができる。
ソースではmodule ApplicationHelperがモジュールとして定義されている
4.3.1配列と範囲演算子
splitメソッドを使うと、文字列を自然に変換した配列を得ることができる
例1
"foo bar baz".split
["foo", "bar", "baz"]
例2
"fooxbarxbaz".split('x')
["foo", "bar", "baz"]
・破壊的メソッド
配列の内容を変更したい場合は、そのメソッドに対応する「破壊的」メソッドを使う。
破壊的メソッドの名前には、元のメソッドの末尾に「!」を追加したものを使う
a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]
・to_aメソッド
ハッシュ、範囲オブジェクトなどを配列に変換するメソッド
(0..9).to_a # 丸カッコを使い、範囲オブジェクトに対してto_aを呼びましょう
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
・%w記法(配列)
空白区切りの文字列から配列を作成
a = %w[foo bar baz quux] # %wを使って文字列の配列に変換
=> ["foo", "bar", "baz", "quux"]
・範囲(range)
配列内の要素の範囲を指定する
例1
a = %w[foo bar baz quux] # %wを使って文字列の配列に変換
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]
例2
a = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> a[2..(a.length-1)] # 明示的に配列の長さを使って選択
=> [2, 3, 4, 5, 6, 7, 8, 9]
>> a[2..-1] # 添字に-1を使って選択
=> [2, 3, 4, 5, 6, 7, 8, 9]
4.3.2 ブロック
メソッド呼び出しの際に引数と一緒に渡すことのできる処理のかたまり
(1..5).each { |i| puts 2 * i }
の{ |i| puts 2 * i }部分
do endでも書ける
(1..5).each do |i|
puts 2 * i
end
・symbol-to-proc
&:メソッド名
&で、:メソッド名をProc(手続きオブジェクト)に変換する
↓
すなわち
何かのオブジェクトを引数にとって、
何かのオブジェクトに対してシンボルと同名のメソッドを呼び出す Proc オブジェクトを返す
・symbolとは
文字列と似ているオブジェクトで、ソース上では文字列のように見えているが、
内部的には整数として扱われている。
主に文字列にコロン記号「:」を前置して定義したもの
ハッシュ(dictionary)のキーでよく使われる
・procとは
Procとはブロックを持ち運び便利なオブジェクトにしたもの
4.3.3 ハッシュとシンボル
・ハッシュとは
本質的には配列と同じだが、
インデックスとして整数値以外のものも使える点が配列と異なる。
user["first_name"] = "Michael"
{ "first_name" => "Michael", "last_name" => "Hartl" }
・記法
{ :name => "Michael Hartl" }
{ name: "Michael Hartl" }
ハッシュとしてのデータ構造は全く同じ
・inspectメソッド
オブジェクトを人間が読める形式に変換した文字列を返す。
puts (1..5).to_a.inspect # 配列のリテラルを出力
[1, 2, 3, 4, 5]
省略記法でpを使う
p :name # 'puts :name.inspect' と同じ
4.3.4 CSS、再び
・メソッド呼び出し
Ruby ではメソッド呼び出しの丸カッコは省略してもOK。
# メソッド呼び出しの丸カッコは省略可能。
stylesheet_link_tag("application", "data-turbo-track": "reload")
# 上は以下のように書いても同じ
stylesheet_link_tag "application", "data-turbo-track": "reload"
ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略できる
# 最後の引数がハッシュの場合、波カッコは省略可能。
stylesheet_link_tag("application", { "data-turbo-track": "reload" })
# 上は以下のように書いても同じ
stylesheet_link_tag("application", "data-turbo-track": "reload")
4.4.1 コンストラクタ
・リテラルコンストラクタ
文字列のオブジェクトを暗黙で作成する
s = "foobar" # ダブルクォートは実は文字列のコンストラクタ
・名前付きコンストラクタ
クラス名に対してnewメソッドを呼び出す
s = String.new("foobar") # 文字列の名前付きコンストラクタ
4.4.2 クラスの継承
superclassメソッドを使ってクラス階層を調べることができる
s.class.superclass
4.4.3 組み込みクラスの変更
Rubyに組み込まれている基本クラスは拡張可能で
自分で変更できる
4.4.5ユーザークラス
・initializeメソッド
クラスをnewしたときに呼び出されるメソッド
attributesという引数を1つ取る
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
感想
今まではC#やjavascriptのコーディング経験がありましたが
改めてRubyでは簡単にコードを記述することができることを実感しました。
symbol-to-procの概念が他にはないものだったので理解するのに時間がかかりましたが
今後もどんどん活用していきたいです!