LoginSignup
1
2

More than 5 years have passed since last update.

Rails風味のRubyを学ぶ

Last updated at Posted at 2018-08-21

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>"
1
2
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
1
2