Railsのtutorial「第4章 Rails風味のRuby」の内容になります。
カスタムヘルパー
ページタイトルを生成するメソッドを作成
app/helpers/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
app/views/layouts/application.html.erb
<title><%= full_title(yield(:title)) %></title>
Railsコンソールで実行結果を確認
$ rails console
数字と文字列
>> 17 + 42
=> 59
>> "foo" + "bar"
=> "foobar"
>> first_name = "Michael"
=> "Michael"
>> "#{first_name} Hartl"
=> "Michael Hartl"
putsとprint
>> puts "foo"
foo # 改行される
=> nil
>> print "foo"
foo=> nil # 改行されない
>> print "foo\n" # 改行文字で改行
foo
=> nil
シングルクォート
>> 'foo'
=> "foo"
>> 'foo' + 'bar'
=> "foobar"
# シングルクォート内の文字列では式展開ができない
>> '#{foo} bar'
=> "\#{foo} bar"
# 'バックスラッシュ n' をそのまま扱う
>> '\n'
=> "\\n"
論理値を返す/条件文/オブジェクト
Rubyではあらゆるものがオブジェクトである。文字列やnilもオブジェクトである
>> "foobar".length
=> 6
論理値(boolean)を返すときに末尾に疑問符を示す
>> s = "foobar"
>> if s.empty?
>> "The string is empty"
>> else
>> "The string is nonempty"
>> end
=> "The string is nonempty"
条件文を2つ以上含めたいとき
>> if s.nil?
>> "The variable is nil"
>> elsif s.empty?
>> "The string is empty"
>> elsif s.include?("foo")
>> "The string includes 'foo'"
>> end
=> "The string includes 'foo'"
論理値and/or/not
>> x = "foo"
=> "foo"
>> y = ""
=> ""
>> puts "Both strings are empty" if x.empty? && y.empty?
=> nil
>> puts "One of the strings is empty" if x.empty? || y.empty?
"One of the strings is empty"
=> nil
>> puts "x is not empty" if !x.empty?
"x is not empty"
=> nil
nilもオブジェクト
>> nil.to_s
=> ""
>> nil.empty?
NoMethodError: undefined method `empty?' for nil:NilClass
# メソッドチェーン
>> nil.to_s.empty?
=> true
>> "foo".nil?
=> false
>> "".nil?
=> false
>> nil.nil?
=> true
ifを後に書くこともできる
x = "foo"
puts "x is not empty" if !x.empty?
=> x is not empty
!!(バンバン)で強制的に論理値にする
>> !!nil
=> false
>> !!0
=> true
railsコンソールでメソッドを定義することもできる
>> def string_message(str = '')
>> if str.empty?
>> "It's an empty string!"
>> else
>> "The string is nonempty."
>> end
>> end
=> :string_message
>> puts string_message("foobar")
The string is nonempty.
>> puts string_message("")
It's an empty string!
>> puts string_message
It's an empty string!
文字列を配列に変換
>> "foo bar baz".split
=> ["foo", "bar", "baz"]
>> "fooxbarxbaz".split('x')
=> ["foo", "bar", "baz"]
配列の要素を取得
>> a = [42, 8, 17]
=> [42, 8, 17]
>> a[0]
=> 42
>> a[1]
=> 8
>> a[2]
=> 17
>> a[-1]
=> 17
>> a.first
=> 42
>> a.second
=> 8
>> a.last
=> 17
>> a.last == a[-1]
=> true
配列にメソッド
>> a = [42, 8, 17]
=> [42, 8, 17]
>> a.empty?
=> false
>> a.include?(42)
=> true
>> a.sort
=> [8, 17, 42]
>> a.reverse
=> [17, 8, 42]
>> a.shuffle
=> [17, 42, 8]
>> a
=> [42, 8, 17]
破壊的メソッド
メソッドの末尾に「!」を追加
>> a = [42, 8, 17]
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]
push(<<)メソッドで要素追加
>> a = [42, 8, 17]
=> [42, 8, 17]
>> a.push(6)
=> [42, 8, 17, 6]
>> a << 7
=> [42, 8, 17, 6, 7]
>> a << "foo" << "bar"
=> [42, 8, 17, 6, 7, "foo", "bar"]
配列から文字列に変換
>> a = [42, 8, 17, 6, 7, "foo", "bar"]
=> [42, 8, 17, 6, 7, "foo", "bar"]
>> a.join
=> "4281767foobar"
>> a.join(', ')
=> "42, 8, 17, 6, 7, foo, bar"
rangeとto_a
to_aは配列に変換するメソッド
>> (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> a = %w[foo bar baz quux]
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]
>> 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]
=> [2, 3, 4, 5, 6, 7, 8, 9]
>> ('a'..'e').to_a
=> ["a", "b", "c", "d", "e"]
each
>> (1..5).each { |i| puts 2 * i } # 1行のとき {}
2
4
6
8
10
=> 1..5
>> (1..5).each do |i| # 複数行のとき do end
?> puts 2 * i
>> end
2
4
6
8
10
=> 1..5
times
>> 3.times { puts "Betelgeuse!" } # 3.timesではブロックに変数を使っていない
"Betelgeuse!"
"Betelgeuse!"
"Betelgeuse!"
=> 3
map
>> (1..5).map { |i| i**2 } # 「**」記法は冪乗 (べき乗)
=> [1, 4, 9, 16, 25]
>> %w[a b c] # %w で文字列の配列を作成
=> ["a", "b", "c"]
>> %w[a b c].map { |char| char.upcase }
=> ["A", "B", "C"]
>> %w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]
>> %w[A B C].map(&:downcase) # 省略記法
=> ["a", "b", "c"]
ハッシュ(連想配列)
ハッシュの波カッコは、ブロックの波カッコとはまったく別物である
>> user = {} # {}は空のハッシュ
=> {}
>> user["first_name"] = "Michael" # キーが "first_name" で値が "Michael"
=> "Michael"
>> user["last_name"] = "Hartl" # キーが "last_name" で値が "Hartl"
=> "Hartl"
>> user["first_name"] # 要素へのアクセスは配列の場合と似ている
=> "Michael"
>> user # ハッシュのリテラル表記
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}
>> user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}
シンボルを使ったハッシュ
>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name] # :name に対応する値にアクセスする
=> "Michael Hartl"
>> user[:password] # 未定義のキーに対応する値にアクセスする
=> nil
コロンとハッシュロケット
>> h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h1 == h2
=> true
ハッシュとeach
>> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> flash.each do |key, value|
?> puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :danger has value "It failed."
inspect
オブジェクトを表現する文字列を返す
>> puts (1..5).to_a # 配列を文字列として出力
1
2
3
4
5
>> puts (1..5).to_a.inspect # 配列のリテラルを出力
[1, 2, 3, 4, 5]
>> puts :name, :name.inspect
name
:name
>> puts "It worked!", "It worked!".inspect
It worked!
"It worked!"
inspectのショートカットpメソッド
>> p :name # 'puts :name.inspect' と同じ
:name
blankとempty
Railsはblank?メソッドをRubyに追加
>> "".blank?
=> true
>> " ".empty?
=> false
>> " ".blank?
=> true
>> nil.blank?
=> true
CSSファイル読み込みについて
stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
- メソッド呼び出しで丸カッコは不要(stylesheet_link_tag())
- メッシュ呼び出しの最後の引数はハッシュ不要({media: 'all', 'data-turbolinks-track': 'reload'})
- 途中で改行されても空白行とはみなさない
- 第一引数の文字列はスタイルシートへのパス
実際のHTMLソース
<link data-turbolinks-track="true" href="/assets/application.css"
media="all" rel="stylesheet" />
クラス
Rubyは多くのオブジェクト指向言語と同様、メソッドをまとめるのにクラスを使っています。
これらのクラスからインスタンスが生成されることでオブジェクトが作成されます。
コンストラクタ
ダブルクォートは文字列のコンストラクタ
>> s = "foobar"
=> "foobar"
>> s.class
=> String
名前付きコンストラクタはnewメソッド呼び出す
文字列
>> s = String.new("foobar")
=> "foobar"
>> s.class
=> String
>> s == "foobar"
=> true
配列
>> a = Array.new([1, 3, 2])
=> [1, 3, 2]
ハッシュ
>> h = Hash.new
=> {}
>> h[:foo] # 存在しないキー (:foo) の値にアクセスしてみる
=> nil
>> h = Hash.new(0) # 存在しないキーのデフォルト値をnilから0にする
=> {}
>> h[:foo]
=> 0
クラス継承
Rubyにおけるすべてのクラスは最終的にスーパークラスを持たないBasicObjectクラスを継承
>> s = String.new("foobar")
=> "foobar"
>> s.class # 変数sのクラスを調べる
=> String
>> s.class.superclass # Stringクラスの親クラスを調べる
=> Object
>> s.class.superclass.superclass # Ruby 1.9からBasicObjectが導入
=> BasicObject
>> s.class.superclass.superclass.superclass
=> nil
Wordクラスを定義
>> class Word < String
>> def palindrome?
>> self == self.reverse # selfは文字列自身を表します
>> end
>> end
=> :palindrome?
>> s = Word.new("level")
=> "level"
>> s.palindrome?
=> true
>> s.length
=> 5
>> s.class
=> Word
>> s.class.superclass
=> String
>> s.class.superclass.superclass
=> Object
controllerの継承関係
>> controller = StaticPagesController.new
=> #<StaticPagesController:0x22855d0>
>> controller.class
=> StaticPagesController
>> controller.class.superclass
=> ApplicationController
>> controller.class.superclass.superclass
=> ActionController::Base
>> controller.class.superclass.superclass.superclass
=> ActionController::Metal
>> controller.class.superclass.superclass.superclass.superclass
=> AbstractController::Base
>> controller.class.superclass.superclass.superclass.superclass.superclass
=> Object
Userクラスを作ってみる
class User
attr_accessor :name, :email
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
def formatted_email
"#{@name} <#{@email}>"
end
end
>> require './example_user'
=> true
>> example = User.new
=> #<User:0x224ceec @email=nil, @name=nil>
>> example.name = "Example User"
=> "Example User"
>> example.email = "user@example.com"
=> "user@example.com"
>> example.formatted_email
=> "Example User <user@example.com>"