Rails-tutorial自分用まとめ(4章 Ruby )

その3から続く

4章Rails風味のRuby

4.1.1 組み込みヘルパー

サンプルアプリケーションのレイアウト
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
        'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
        'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

stylesheet_link_tag (詳細はRails API参照) を使って、application.cssをすべてのメディアタイプで使えるようにしています

4.1.2 カスタムヘルパー

新しく作ったメソッドはカスタムヘルパー

<%= yield(:title) %> | Ruby on Rails Tutorial Sample App
<% 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>

full_titleというヘルパーを作成することにします。

full_titleヘルパーを定義する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
<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
<title><%= full_title(yield(:title)) %></title>

full_titleヘルパーを使ったWebサイトのレイアウト green

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
<title><%= full_title(yield(:title)) %></title>    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

 Homeページのタイトル確認用にテストを更新する red

test/controllers/static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  test "should get home" do
    get static_pages_home_url
    assert_response :success
assert_select "title", "Ruby on Rails Tutorial Sample App"  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end
end
rails test
3 tests, 6 assertions, 1 failures, 0 errors, 0 skips

ページタイトルをカスタマイズせずに表示するHomeページ green

app/views/static_pages/home.html.erb
<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>
irbを使うための準備
nano ~/.irbrc

irbの設定ファイルを追加する ~/.irbrc

IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:AUTO_INDENT_MODE] = fals

4.2.2 文字列

rails console
>> ""         # 空の文字列
=> ""
>> "foo"      # 空ではない文字列
=> "foo"
"foo" + "bar"    # 文字列の結合
=> "foobar"

式展開 (interpolation) 

first_name = "Michael"    # 変数の代入
=> "Michael"
>> "#{first_name} Hartl"     # 文字列の式展開
=> "Michael Hartl"

文字列を組み立てる他の方法として式展開 (interpolation)
というものがあり、#{}という特殊な構文を使うよ

=> "Michael Hartl"
>> first_name = "Michael"
=> "Michael"
>> last_name = "Hartl"
=> "Hartl"
>> first_name + " " + last_name
=> "Michael Hartl"
>> "#{first_name} #{last_name}"
=> "Michael Hartl"

first_name変数に代入 (assign)し、この変数を "#{first_name} Hartl"

という形で文字列の中に埋め込むと、文字列の中でその変数が展開されるようになります。

first_name = "Michael"
=> "Michael"
>> last_name = "Hartl"
=> "Hartl"
>> first_name + " " + last_name    # 苗字と名前の間に空白を入れた結合
=> "Michael Hartl"
>> "#{first_name} #{last_name}"    # 式展開を使って結合 (上と全く同じ)
=> "Michael Hartl"

最後の2つの結果は、全く同じ結果(等価という)

Rubyはシングルクォート文字列の中では式展開を行いません。

>> '#{first_name}'
=> "\#{first_name}"
>> "#{first_name}"
=> "Michael"

ダブルクォート文字列を用いた文字列で#のような特殊な文字を使いたい場合は、
この文字をバックスラッシュでエスケープ (escape) する必要があります。

>> "\#{first_name}" ×
=> "\#{first_name}"
>> "\##{first_name}"○
=> "#Michael"

シングルクォートは、入力した文字をエスケープせずに「そのまま」
保持するときに便利。
「バックスラッシュ」の文字は、改行文字\nと同様に多くのシステム上で、特殊な文字として扱われシングルクォートで文字列を囲めば、簡単にバックスラッシュ文字の
ような特殊文字をそのまま変数に含めることができるよ。

>> '\n'
=> "\\n"

#{文字と同様、Rubyでバックスラッシュそのものをエスケープする場合は、
バックスラッシュがもう1つ必要でダブルクォート文字列の中では、
バックスラッシュ文字そのものは2つのバックスラッシュによって表され
次のようにエスケープの必要な文字が大量にある場合には、
シングルクォートは非常に便利。

>> 'Newlines (\n) and tabs (\t) both use the backslash
character \.'
=> "Newlines (\\n) and tabs (\\t) both use the backslash
character \\."

演習

1:city変数に適当な市区町村を、prefecture変数に適当な都道府県を
代入してください。

city = 'iga'
prefecture = 'mie'

2:先ほど作った変数と式展開を使って、「東京都新宿区」のような
住所の文字列を作ってみましょう。出力にはputsを使ってください。

"#{prefecture}県 #{city}市"
=> "mie県 iga市"

3:上記の文字列の間にある半角スペースをタブに置き換えてみてください。
(ヒント: 改行文字と同じで、タブも特殊文字です)

puts "#{prefecture}県 \t #{city}
mie県 iga市

4:タブに置き換えた文字列を、ダブルクォートからシングルクォートに
置き換えてみるとどうなるでしょうか?

puts '#{prefecture}県 \t #{city}市'
#{prefecture}県 \t #{city}市

4.2.3 オブジェクトとメッセージ受け渡し

Rubyでは、あらゆるものがオブジェクトです。文字列やnilですらオブジェクトです。オブジェクトとは (いついかなる場合にも) メッセージに応答するものです。

オブジェクトは、例えばlengthというメッセージに応答できますが、これは文字列の文字数を返します。

"foobar".length        # 文字列に "length" というメッセージを送る
=> 6
"foobar".empty?
=> false
>> "".empty?
=> true

> first_name = “Michael” # 変数の代入
=> “Michael”
>> “#{first_name} Hartl” # 文字列の式展開
=> “Michael Hartl”

「!!」(「バンバン (bang bang)」と読みます) という演算子を使うと、
そのオブジェクトを2回否定することになるので、どんなオブジェクトも
強制的に論理値に変換できます

!!nil => false

その他のあらゆるRubyのオブジェクトは、ゼロですらtrueです。

>> !!0 => true

オブジェクトに渡されるメッセージは、一般にはメソッドと呼ばれ
メソッドの実体は、そのオブジェクト内で定義されたメソッドです
メソッドをチェーン(chain)して渡せます。

nil.to_s.empty? # メソッドチェーンの例
=> true

出力

puts "foo"     # 文字列を出力する
foo
=> nil
print "foo"    # 文字列の画面出力 (putsと同じだが改行がない)
foo=> nil

意図的に改行を追加したいときは、
「バックスラッシュ (\) + n」( \n) という改行文字を使います。

print "foo\n"  # puts "foo" と等価
foo
=> nil

シングルクォート内の文字列

'foo'          # シングルクォートの文字列
=> "foo"
>> 'foo' + 'bar'
=> "foobar"

Rubyはシングルクォート文字列の中では式展開を行いません。

'#{foo} bar'     # シングルクォート内の文字列では式展開ができない
=> "\#{foo} bar"

#のような特殊な文字を使いたい場合は、この文字をバックスラッシュでエスケープ (escape) 

演習

1:”racecar” の文字列の長さはいくつですか? lengthメソッドを
使って調べてみてください。

"racecar".length => 7

2:reverseメソッドを使って、”racecar”の文字列を逆から読むと
どうなるか調べてみてください。

"racecar".reverse => "racecar"

3:変数sに “racecar” を代入してください。その後、比較演算子 (==)
を使って変数sとs.reverseの値が同じであるかどうか、調べてみてください。

>> s = "racecar" => "racecar"
>> s == s.reverse => true

4:puts “It’s a palindrome!” if s == s.reverseを実行すると、どんな結果になるでしょうか?
変数sに “onomatopoeia” という文字列を代入するとどうなるでしょうか?

puts "It's a palindrome!" if s == s.reverse
It's a palindrome! => nil

s = "onomatopoeia" => "onomatopoeia"

puts "It's a palindrome!" if s == s.reverse
=> nil

def string_message(str = '')
  if str.empty?
    "It's an empty string!"
  else
    "The string is nonempty."
  end
end
:string_message
puts string_message
It's an empty string!

puts string_messageのようにメソッドの引数を省略することも可能です(カッコですら省略可能)。

def string_message(str = '')

引数にデフォルト値を含めているからで
引数を渡さない場合は、指定のデフォルト値が自動的に使われるます。

Rubyのメソッドには「暗黙の戻り値がある」ことに注意。これは、
メソッド内で最後に評価された式の値が自動的に返されることを意味する
(メソッドで戻り値を明示的に指定しなかった場合の動作)

メソッドで引数の変数名にどんな名前を使っても、メソッドの呼び出し側には
何の影響も生じないという点にもご注目ください。つまり、最初の例のstrを
別の変数名 (the_function_argumentなど) に変更しても、
メソッドの呼び出し方は全く同じです

>> def string_message(the_function_argument = '')
>> if the_function_argument.empty?
>> "It's an empty string!"
>> else
>> "The string is nonempty."
>> end
>> end
=> :string_message
>> puts string_message("")
It's an empty string!
>> puts string_message("foobar")
The string is nonempty.

演習

1:FILL_INの部分を適切なコードに置き換え、回文かどうかを
チェックするメソッドを定義してみてください。

def palindrome_tester(s)
  if FILL_IN
    puts "It's a palindrome!"
  else
    puts "It's not a palindrome."
  end
end

FILL_IN s == s.reverse

2:上で定義したメソッドを使って “racecar” と “onomatopoeia” が回文か
どうかを確かめてみてください。1つ目は回文である、2つ目は回文でない、
という結果になれば成功です。

>>palindrome_tester("racecar")
=>It's a palindrome! => nil

>>palindrome_tester("onomatopoeia")
=>It's not a palindrome. => nil

3:palindrome_tester(“racecar”)に対してnil?メソッドを呼び出し、
戻り値がnilであるかどうかを確認してみてください

def palindrome_tester(s) def palindrome_tester(s = '')
  if s == s.reverse
   puts "It's a palindrome!"
    else
   puts "It's not a palindrome."
    end
 end
:palindrome_tester
puts palindrome_tester('racecar')

下でもOK

def palindrome_tester(s = 'racecar')
  if s == s.reverse
    puts "It's a palindrome!"
  else
    puts "It's not a palindrome."
  end
end

:palindrome_tester
palindrome_tester.nil?

()がない場合はデフォルトで設定したもの(1行目)が引数にあるので

module ApplicationHelper

 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

モジュールは、関連したメソッドをまとめる方法の1つで、
※includeメソッドを使ってモジュールを読み込むことができるよ
(ミックスイン (mixed in) とも呼ぶ
Railsでは自動的にヘルパーモジュールを読み込んでくれるので、
include行をわざわざ書く必要がない。
つまり、このfull_titleメソッドは自動的にすべてのビューで
利用できるようになっている、ということ。

4.5に続きます

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です