0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsチュートリアル4章まとめ

Last updated at Posted at 2021-02-12

#この章で学ぶこと
基本的なRubyの構文を学ぶ
基礎をある程度知っていればこの章は程々に流し見すればOK

  • helper
  • Ruby自体の文字列、オブジェクト
  • メソッド
  • 配列、範囲演算子
  • ブロック{}
  • ハッシュとシンボル (#タグではありません)
  • クラス、クラスの継承

4.1.2 カスタムヘルパー

ビューなどで新しく作ったメソッドはカスタムヘルパー と呼ぶ

まずはfull_titleというヘルパーを作成する
full_titleヘルパーは、ページタイトルが定義されていない場合は基本タイトル「Ruby on Rails Tutorial Sample App」を返し、定義されている場合は基本タイトルに縦棒とページタイトルを追加して返す

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>
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title> #full_titleメソッド
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application',
                               'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

タイトルの表示方法を変更したので、testも更新する

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

この状態ではtestは失敗するので、

Homeページのビューからprovide の行を削除する

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>

これでtestはパスする。
4章でsample_app自体を触るのはこれで最後。
あとはrails consoleでRuby自体を学ぶ

##4.2 文字列とメソッド

今後、Ruby詳細が知りたければ、Rubyリファレンスマニュアル(通称: るりま)や、るりまサーチを使うと便利
https://docs.ruby-lang.org/ja/
https://docs.ruby-lang.org/ja/search/

###4.2.1 文字列
文字列(string) は、Webアプリケーションにおいて最も重要なデータ構造
理由はWebページというものが究極的にはサーバーからブラウザに送信された文字列にすぎないため

$ rails console
>> ""         # 空の文字列
=> ""
>> "foo"      # 空ではない文字列
=> "foo"
ここで入力したものは文字列リテラルと呼ばれダブルクォート " で囲むことで作成可能

+演算子を使って、文字列を結合する

>> "foo" + "bar"    # 文字列の結合
=> "foobar"

####式展開(interpolation)=#{}という特殊な構文を使う

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

例えば"Michael"という値を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つの結果は、全く同じ結果(「等価」と言います)

####putsで文字列を出力可能
※putの三人称単数現在形ではなく「put string」の略

	>> puts "foo"     # 文字列を出力する
	foo
	=> nil   #副作用

putsメソッドでは副作用が重要な役割を果たす
puts "foo"は文字列「"foo"」を副作用としてスクリーンに表示し、戻り値にはnilを返す
nilは「何にもない」ことを表すRubyの特別な値

putsを使って出力すると、改行文字である\nが自動的に出力の末尾に追加される
似たメソッドでprintメソッドも同様の出力を行うが、改行文字を追加しない点が異なる

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

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

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

####railsではダブルクォート文字列でもはシングルクォートでもOK。
ほとんどの場合、ダブルクォートとシングルクォートのどちらを使っても実質的に同じだが、式展開はシングルクォートでは行われない

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

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

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

※バックスラッシュは¥マークのボタン(mac) option+¥でできる
https://qiita.com/miyohide/items/6cb8967282d4b2db0f61

>> '\n'       # 'バックスラッシュ n' をそのまま扱う
=> "\\n"

###オブジェクト指向
Rubyでは、あらゆるものがオブジェクト。文字列やnilですらオブジェクト。
オブジェクト指向って何?となりますが、これは概念のようなもので、実際に触りながらこんなものかと覚えていくしかないようです。
↓参考ページ
https://www.sejuku.net/blog/124336#:~:text=Ruby%E3%81%AF%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E5%9E%8B,%E3%81%BE%E3%81%A8%E3%82%81%E3%81%9F%E9%96%8B%E7%99%BA%E5%BD%A2%E5%BC%8F%E3%81%A7%E3%81%99%E3%80%82

文字列オブジェクトは、直接メソッドをつなげられる
※lengthメソッド=文字列の文字数を返す。

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

####?疑問符でtrueまたはfalseという論理値(boolean)を返せる

>> "foobar".empty?  #文字列に"empty?"メソッドを送る
=> false
>> "".empty?
=> true
#以下のif文と等価
>> s = "foobar"
>> if s.empty?
>>   "The string is empty"
>> else
>>   "The string is nonempty"
>> end
=> "The string is nonempty"

####条件文を2つ以上含めたい場合は、elsif (else + if) という文を使う

	>> if s.nil?  #もしsがnilなら(trueなら)
	>>   "The variable is nil"
	>> elsif s.empty?  #もしsが空なら(trueなら)
	>>   "The string is empty"
	>> elsif s.include?("foo") #もしsが"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もオブジェクトなので、メソッドに対応可能

オブジェクトを文字列に変換するto_sメソッドを使って、nilがメソッドに応答する例

>> nil.to_s
=> ""
#確かに空文字列が出力される

####メソッドチェイン(method chaining)でnilにいろんなオブジェクトを渡す

>> nil.empty?
NoMethodError: undefined method `empty?' for nil:NilClass
>> nil.to_s.empty?      # メソッドチェーンの例
=> true
#nilオブジェクト自身はempty?メソッドには応答しないにもかかわらず、nil.to_sとすると応答する

####nilかどうかを調べるメソッドnil?

	>> "foo".nil?
	=> false
	>> "".nil?
	=> false
	>> nil.nil?
	=> true

####ifの簡潔な使い方

puts "x is not empty" if !x.empty?
#もしxが空(true)でないなら...

後続するifでの条件式が真のときにだけ実行される式(後続if)を書くことができ、コードが非常に簡潔になる

unlessキーワードも同様に使える

>> string = "foobar"
>> puts "The string '#{string}' is nonempty." unless string.empty?
#stringが空(true)でない(false)なら...
The string 'foobar' is nonempty.
=> nil

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

>> !!nil  #nilのまま
=> false
#ゼロですらtrue
>> !!0
=> true

###4.2.3 メソッドの定義

	>> 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") #string_messageメソッドに"foobar"引数で実行
	The string is nonempty.
	>> puts string_message("")#string_messageメソッドに""引数で実行
	It's an empty string!
	>> puts string_message    #引数与えなければデフォルトの引数''で実行
	It's an empty string!

###4.3.1 配列と範囲演算子
配列(array)は、特定の順序を持つ要素のリスト

>>  "foo bar baz".split     # 文字列を3つの要素を持つ配列に分割する
=> ["foo", "bar", "baz"]

foo,bar,bazの3つの文字列からなる配列が得られます。
splitは文字列を区切って配列にするが、
次のようにsplit('x')引数を渡して他の文字を指定して区切ることもできる

>> "fooxbarxbaz".split('x')
=> ["foo", "bar", "baz"]

####配列の中の番号は1からではなく0から数える

>> a = [42, 8, 17]
=> [42, 8, 17]
>> a[0]               # Rubyでは角カッコで配列にアクセスする
=> 42
>> a[1]
=> 8
>> a[2]
=> 17
>> a[-1]              # 配列の添字はマイナスにもなれる!
=> 17

####firstやsecondメソッドでも取り出せる

>> a                  # 配列「a」の内容を確認する
=> [42, 8, 17]
>> a.first
=> 42
>> a.second
=> 8
>> a.last
=> 17
>> a.last == a[-1]    # == を使って比較する
=> true

####lengthメソッドで配列の数も返すことができる

>> x = a.length       # 配列も文字列と同様lengthメソッドに応答する
=> 3
>> x == 3
=> true
>> x == 1
=> false
>> x != 1
=> true
>> x >= 1
=> true
>> x < 1
=> false

####lengthメソッド以外にも、さまざまなメソッドに応答する

>> a
=> [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自身は変更されていない
####配列の内容を変更するには「破壊的メソッド」を使う
破壊的メソッドの名前には、元のメソッドの末尾に「!」を追加する

>> a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42]

####pushメソッド(または同等の<<演算子)を使って配列に要素を追加するのも可能

>> a.push(6)                  # 6を配列に追加する
=> [42, 8, 17, 6]
>> a << 7                     # 7を配列に追加する push 7でもOK
=> [42, 8, 17, 6, 7]
>> a << "foo" << "bar"        # 配列に連続して追加する
=> [42, 8, 17, 6, 7, "foo", "bar"]

####joinメソッドで配列を一つの文字列にできる→splitの反対

>> a
=> [42, 8, 17, 6, 7, "foo", "bar"]
>> a.join                       # 単純に連結する
=> "4281767foobar"
>> a.join(', ')                 # カンマ+スペースを使って連結する
=> "42, 8, 17, 6, 7, foo, bar"

####範囲 (a..z)で範囲を作れる
to.aメソッド(to array)は配列にするメソッド to.aを使う際は()で範囲オブジェクトにする

>> 0..9
=> 0..9
>> 0..9.to_a              # おっと、9に対してto_aを呼んでいるのでエラー 
NoMethodError: undefined method `to_a' for 9:Fixnum
>> (0..9).to_a            # 丸カッコを使い、範囲オブジェクトに対してto_aを呼びましょう
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

####範囲は、配列の要素を取り出すのに便利

>> a = %w[foo bar baz quux]         # %wを使って文字列の配列に変換
=> ["foo", "bar", "baz", "quux"]
>> a[0..2]
=> ["foo", "bar", "baz"]

####インデックスに-1を使うと、配列の長さを知らなくても配列の最後の要素を指定することができる

>> 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]
#次のように、文字列に対しても範囲オブジェクトが使える
>> ('a'..'e').to_a
=> ["a", "b", "c", "d", "e"]

###4.3.2 ブロック

  • eachメソッドに渡されている{ |i| puts 2 * i }が、ブロックと呼ばれる
  • ブロック内|i|はブロックを操作するときに使う変数
  • 以下の場合、範囲オブジェクトのeachメソッドは、iという1つの変数を使ってブロックを操作
  • 範囲に含まれるそれぞれの値をこの変数に次々に代入してブロックを実行する
  • 1..5に対しi(1..5)それぞれに2をかける
>> (1..5).each { |i| puts 2 * i }
2
4
6
8
10
=> 1..5

####ブロックはdoとendで囲んで示すこともできる

?>   puts 2 * i
>> end
2
4
6
8
10
=> 1..5

####ブロックの中は複数行もOK

>> (1..5).each do |number|
?>   puts 2 * number
>>   puts '--'
>> end
2
--
4
--
6
--
8
--
10
--
=> 1..5
#今度はiの代わりにnumberを使っている  変数名は指定なし

####その他の使用例 times,map

>> 3.times { puts "Betelgeuse!" }   # 3.timesではブロックに変数を使っていない
"Betelgeuse!"
"Betelgeuse!"
"Betelgeuse!"
=> 3
>> (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 } #upcaseは大文字にするメソッド
=> ["A", "B", "C"]
>> %w[A B C].map { |char| char.downcase } #douncaseは小文字にするメソッド
=> ["a", "b", "c"]

####&シンボルの使い方もある

>> %w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]
>> %w[A B C].map(&:downcase) 
=> ["a", "b", "c"]

####testもブロックで書かれていた

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

###4.3.3 ハッシュとシンボル

  • ハッシュは配列と基本的には同じ
  • ハッシュの場合インテックス番号以外のキーを付けれる
  • ハッシュは、キーと値のペアを波カッコで囲んで表記します{"last_name"=>"Hartl", "first_name"=>"Michael"}
  • キーと値のペアを持たない波カッコの組({})は空のハッシュ
  • ハッシュの波カッコは、ブロックの波カッコとはまったく別物
  • ハッシュは配列との重要な違いはハッシュでは要素の「並び順」が保証されない。もし要素の順序が重要である場合は、配列を使う
>> 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"}

####キーは文字列よりシンボルを使う方が一般的
シンボルはコロンが前に置かれている
:nameのように
####シンボルと文字列では使えるメソッドが異なる

>> "name".split('')
=> ["n", "a", "m", "e"]
>> :name.split('')  #シンボルは文字列と違うのでメソッドができない
NoMethodError: undefined method `split' for :name:Symbol
>> "foobar".reverse
=> "raboof"
>> :foobar.reverse #
NoMethodError: undefined method `reverse' for :foobar:Symbol

####ハッシュの実例

>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name]              # :name に対応する値にアクセスする
=> "Michael Hartl"
>> user[:password]          # 未定義のキーに対応する値にアクセスする
=> nil
 #未定義のハッシュ値はniになる

####ハッシュは以下のようにも記載可能 (こっちの方が人気)

>> 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

####ハッシュの中にハッシュを入れることもできる

>> params = {}        # 'params' というハッシュを定義する ('parameters' の略)。
=> {}
>> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" }
=> {:name=>"Michael Hartl", :email=>"mhartl@example.com"}
>> params
=> {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}}
>>  params[:user][:email]
=> "mhartl@example.com"

#####ハッシュも配列や範囲オブジェクトと同様、eachメソッドに応答
配列のeachメソッドでは、ブロックの変数は1つだけですが、ハッシュのeachメソッドでは、ブロックの変数はキーと値の2つになっている
→ハッシュに対してeachメソッドを実行すると、ハッシュの1つの「キーと値のペア」ごとに処理を繰り返す

>> 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."

####シンボルはpメソッドを使うと文字列として表示できる

>> p :name             # 'puts :name.inspect' と同じ
:name

###4.3.4 CSS、再び
メソッドなどの理解をした上で、CSS(cascading style sheet)に追加した以下行の解説
※CSSがcascading style sheetの略ということを初めて知りました

<%= stylesheet_link_tag 'application', media: 'all',
                                       'data-turbolinks-track': 'reload' %>

####Rubyでは丸括弧()を使用しなくてもいい
次の2つの行は等価です。

# メソッド呼び出しの丸カッコは省略可能。
stylesheet_link_tag('application', media: 'all',
                                   'data-turbolinks-track': 'reload')
# 上は以下のように書いても同じ
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

大きな目で見るとstylesheet_link_tag()というメソッドが使われている

####ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略可能
media引数はハッシュのようですが、波カッコがない点が不思議です。実は、ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略できます。次の2つの行は等価です。

# 最後の引数がハッシュの場合、波カッコは省略可能。
stylesheet_link_tag 'application', { media: 'all',
                                     'data-turbolinks-track': 'reload' }
# 上は以下のように書いても同じ
stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

大きな目で見ると、stylesheet_link_tagの引数は

  • application' 第一引数
  • {media: 'all','data-turbolinks-track': 'reload'} =第二引数 となる

####Rubyは空白と改行を区別しない

stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

なので改行して読みやすくしている

まとめると
stylesheet_link_tagメソッドで 第一引数の文字列 'application'はスタイルシートへのパス
第二引数のハッシュ media: 'all','data-turbolinks-track': 'reload'は最初の要素はメディアタイプ、二つ目はturbolinksという機能をオンにしている

ここの部分をHTMLソースとして見るとこうなる

<link rel="stylesheet" media="all" href="/assets/application.self-
f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1"
data-turbolinks-track="reload" />

###クラス

###4.4.1 コンストラクタ
コンストラクタとはなんぞ?と思ったので、調べてみました。
https://wa3.i-3-i.info/word13646.html
https://www.fenet.jp/dotnet/column/language/3861/#i

一言でいうとクラスをnewした瞬間に実行される関数

今までの文字列を""で囲っていた””もリテラルコンストラクタに当たる

>> s = "foobar"       # ダブルクォートは実は文字列のコンストラクタ
=> "foobar"      #""でfoobarという文字列のインスタンスを作っていた
>> s.class    #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

Hashと言うクラス自身に対して呼び出されるメソッド(newの部分)=クラスメソッド
Hash.newで呼び出した結果=クラスのオブジェクト、インスタンス
h.lengthのようなインスタンスに対して呼び出すメソッド=インスタンスメソッド

###4.4.2 クラス継承
superclassメソッドを使ってクラス階層を調べられる

>> 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

foobarのクラスはString>Object>BasicObjectとなる

####クラスについての理解を深めるために自分でクラスを作ってみる
(回文を返すメソッド)

>> class Word
>>   def palindrome?(string)
>>     string == string.reverse
>>   end
>> end
=> :palindrome?

####wordクラスの使い方

>> w = Word.new              # Wordオブジェクトを作成する
=> #<Word:0x22d0b20>
>> w.palindrome?("foobar")
=> false
>> w.palindrome?("level")
=> true

####単語は文字列のためStringクラスを継承する(している)

>> class Word < String             # WordクラスはStringクラスを継承する
>>   # 文字列が回文であればtrueを返す
>>   def palindrome?
>>     self == self.reverse        # selfは文字列自身を表します
>>   end
>> end
=> :palindrome?

####Word < String 記法でStringクラスを継承する。
継承するとStringクラスが扱えるすべてのメソッドがWordクラスでも使える

>> s = Word.new("level")    # 新しいWordを作成し、"level" で初期化する
=> "level"
>> s.palindrome?            # Wordが回文かどうかを調べるメソッド
=> true
>> s.length                 # WordはStringで扱える全てのメソッドを継承している
=> 5

####WordクラスはStringクラスを継承している

>> s.class
=> Word
>> s.class.superclass
=> String
>> s.class.superclass.superclass
=> Object

sクラスはWord<String<Objectクラスを継承している

####selfで自分自身を返すことができる
以下の例ではselfで自分自身を返している
※s=Word.new(引数)で作ったインスタンス自身の名前を反対にしている

>> class Word < String             # WordクラスはStringクラスを継承する
>>   # 文字列が回文であればtrueを返す
>>   def palindrome?
>>     self == self.reverse        # selfは文字列自身を表します
>>   end
>> end
=> :palindrome?

self == self.reverse
なお、Stringクラスの内部では、メソッドや属性を呼び出すときのself.も省略可能

self == reverse
といった省略記法でも、動く

###4.4.3 組み込みクラスの変更
String(文字列)クラス自体にpalindromeメソッドを組み込むことができる
Stringクラスに以下のようにメソッドを追加できる

>> class String
>>   # 文字列が回文であればtrueを返す
>>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> :String
>> "deified".palindrome?
=> true

しかしこれはあまりやらない方がいいらしいです。みんなが使うクラスを勝手に変えるのはよくないですもんね。。

###4.4.4 コントローラクラス
クラスはStaticPagesControllerでも既に使われていた

class StaticPagesController < ApplicationController

  def home
  end

  def help
  end

  def about
  end
end

StaticPagesController は< ApplicationControllerを継承している

>> 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

###4.4.5 ユーザークラス
以下のコードを例題に解説

example_user.rb
class User
  attr_accessor :name, :email

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end

  def formatted_email
    "#{@name} <#{@email}>"
  end
end

####アクセサー
attr_accessor :name, :email
ユーザー名とメールアドレス(属性: attribute)に対応するアクセサー(accessor) をそれぞれ作成している

アクセサーを作るとインスタンス変数@name``@emailへアクセスできるメソッドが用意され、インスタンス変数をコントローラー内で作ればビューで使え得るようになる
※データを取り出すメソッド(getter)と、データに代入するメソッド(setter)をそれぞれ定義

####initializeメソッド
User.newを実行すると自動的に呼び出されるメソッドで
次のようにattributesという引数を1つ取る

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end

上のコードで、attributes変数は空のハッシュをデフォルトの値として持つため、名前やメールアドレスのないユーザーを作る

###initializeメソッドにハッシュを渡すことで、属性が定義済みの他のユーザを作成することができる

##まとめ
4章ではRubyの基本的な文法や配列、ハッシュなどを学んだ

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?