Help us understand the problem. What is going on with this article?

Rubyの基本文法

More than 3 years have passed since last update.

概要

Railsの5.0系が正式リリースされて早3ヶ月が経過しました。
そろそろ触らないとまずいと思い、Rubyの復習からさくっとやりました。

(最近は、Pythonの事ばかり考えていたので、頭の整理もしたかった。)

内容に関しては、主要機能のみをさくっとまとめた感じです。

ターミナル操作

  • irb
    • Intaractive Ruby
    • ターミナルでインタラクティブにコマンドを確認できる。
  • ri
    • ri Arrayなどで命令やオブジェクトのドキュメントを確認できる。

出力系の命令

  • print
    • コンソール出力
  • puts
    • 改行付きコンソール出力
  • p
    • デバッグ用コンソール出力
  • 行末のセミコロンは原則なし
  • コメント
    • #
    • =begin~=end

変数と定数

  • 変数
    • 英語小文字 or _(最初の文字)
    • msg = 'Hello'
  • 定数
    • 英語大文字(最初の文字)
    • 再代入しても、警告は出るが、値は変わってしまう。

Rubyのオブジェクトの概念

オブジェクトの理解

  • 全ての値がオブジェクトである。
    • 'hello world'や1.1など
  • オブジェクトとは何か
    • 便利な命令をたくさん持ったデータ型
      • 'hello world'.length
    • オブジェクトが用意している命令をメソッドと呼ぶ。
  • どのメソッドが使えるかは、その値がどのオブジェクトに属しているかで変わる。

    • オブジェクトの種類の事をクラスと呼ぶ。
      • String Class
      • Float Class
    • Rubyではクラスを上手く使う事でいいプログラムが書ける。
  • 1.1や'hello world'の様な実際の値をインスタンスと呼ぶ。

  • オブジェクトは便利な命令をたくさん持ったデータ型

  • インスタンスは、クラスから生成された実際の値。

    • 型を必ず持つ
    • 型 = クラス

クラスの情報取得メソッド

  • クラスの確認
    • <instance>.class
  • インスタンスが持つメソッドの確認
    • <instance>.methods
  • Fixnumクラス
  • Floatクラス
    • <instance>.round
    • <instance>.floor
    • <instance>.ceil

文字列オブジェクト

  • ""
    • 特殊文字が使える
    • 式展開が可能
  • ''
    • 特殊文字が使えない
    • 式展開が不可能
  • #{}
    • 文字列中でRuby式が評価される。
  • +
    • 文字列を連結できる。
  • *
    • 文字列を繰り返す。

破壊的メソッドと真偽値メソッド

  • !が付くメソッド
    • 破壊的メソッド
      • !なしは単純に値を返すだけ
      • !があるものは、値を返し、元の値も変更する。
      • ただし、感嘆符付きのメソッドが必ずしも破壊的とは限らない。
    • upcase!orupcase
  • ?が付くメソッド
    • 真偽値を返すメソッド
    • ```.empty?
    • ```.include?()

配列オブジェクト

colors = [
  'red',
  'blue',
  'yellow'
]

p colors[0]     # "red"
p colors[-1]    # "yellow"
p colors[0..2]  # ["red", "blue", "yellow"]
p colors[0...2] # ["red", "blue"]
p colors[5]     # nil

colors[0] = 'pink'
colors[1..2] = ['white', 'black']
colors.push('gold')
colors << 'silver'

p colors # ["pink", "white", "black", "gold", "silver"]
p colors.size # 5
p colors.sort # ["black", "gold", "pink", "silver", "white"]

  • 添え字の-値
    • -1で1番後ろの要素
    • -2で後ろから2番目の要素
  • 添え字の範囲指定
    • ..で添え字から添え字まで
    • ...で添え字から添え字の1つ前の添え字まで
  • 要素がない添え字を指定
    • nilを返す
  • 要素の書き換え
    • 添え字を指定して代入
  • 要素の範囲指定入れ替え
    • 添え字を範囲で指定して、配列を代入
  • 要素を末尾に追加
    • <instance>.push(<値>)
    • <instance> << <値>
  • 配列の要素数を返す
    • <instance>.size
  • 配列の順序を並び替える
    • <instance>.sort

ハッシュオブジェクト

  • 辞書型
  • key & value
# アローで表現する
scores = {
  "fujimoto" => 200,
  "horio" => 400
}

# シンボル & アローで表現する
scores = {
  :fujimoto => 200,
  :horio => 400
}

# シンボル & ショートハンドで表現する
scores = {
  fujimoto: 200,
  horio: 400
}

p scores[:fujimoto] # 200
scores[:horio] = 100

p scores # {:fujimoto=>200, :horio=>100}

p scores.size # 2
p scores.keys # [:fujimoto, :horio]
p scores.values # [200, 100]
p scores.has_key?(:fujimoto) # true

シンボルオブジェクト

  • 文字列の様なもの(識別子として利用する)
  • 高速な識別子という認識
    • ハッシュクラスを作成する際に利用する事が多い

オブジェクトの変換

  • <instance>.to_i
    • 数値に変換(integer)
  • <instance>.to_f
    • 小数値に変換(float)
  • <instance>.to_s
    • 文字列に変換(string)
  • <instance>.to_a
    • 配列に変換(array)
    • オブジェクトを配列に変換できる
      • [[:fujimoto, 200], [:horio, 300]]
  • <instance>.to_h
    • ハッシュに変換(hash)

便利な%記法

  • % or %Q
    • 文字列を表現
    • ダブルクォーテーション
    • p %(hello) # "hello"
  • %q
    • 文字列を表現
    • シングルクォーテーション
    • p %q(hello) # 'hello'
  • %W
    • 配列を表現
      • スペース区切り
    • 式展開あり
    • p %W(red blue) # ["red", "blue"]
  • %w
    • 配列を表現
      • スペース区切り
    • 式展開なし
  • %r
    • 正規表現を表現
  • %s

    • シンボルを表現
  • クォーテーションを書かなくてもよくなる。

  • 文字列中でのクォーテションが見やすくなる。

書式付きで値を埋め込む

  • %s
    • 文字列
  • %d
    • 数値
  • %f 小数値
p "name: %s" % 'fujimoto' # "name: fujimoto"
p "id: %05d & rate: %5.2f" % [3, 83.2] # "id: 00003 & rate: 83.20"
  • printf
    • 書式付き文字列をコンソールに表示する
    • ```printf("name: %s", "fujimoto")
  • sprintf
    • 書式付き文字列を返す
    • ```p sprintf("name: %s", "fujimoto")

条件分岐

puts "テストの点数を入力して下さい。"
score = gets.to_i

if score > 80 then
  puts "great!"
elsif score > 60 then
  puts "better"
else
  puts "soso!"
end
  • gets
    • ターミナルでインタラクティブに入力を求める。
  • 条件文のthenは省略可能
  • 最後はendで終わる
  • 論理演算子

    • &&(AND)
    • ||(OR)
    • !(NOT)
  • 1行で書く

p "great" if score >= 20
  • 三項演算子で書く
puts score > 50 ? 'OK' : 'NG'

caseの条件分岐

signal = gets.chomp

case signal
  when 'red'
    p 'stop'
  when 'green', "blue"
    p 'go'
  when 'yellow'
    p 'caution'
  else
    p 'wrong'
end
  • case-when-else-endで記述する。
  • <instance>.chomp
    • 末尾の改行を削除する

制御構造での繰り返し

while

i = 0

while i < 10 do
  p "#{i}: hello"
  i += 1
end

for

  • 配列・ハッシュ・範囲オブジェクト分だけループを回す際に利用する。
colors = [
  'red',
  'blue'
]

scores = {
  fujimoto: 200,
  horio: 300
}

for color in colors do
  p color
end

for name, score in scores do
  p "#{name}: #{score}"
end
  • do-endの部分は{}で表現も可能
  • doは省略可能。

イテレータでの繰り返し

each

  • for文は内部的にeachが使われている為、書き換え可能。
colors = [
  'red',
  'blue'
]

scores = {
  fujimoto: 200,
  horio: 300
}

colors.each do |color|
  p color
end

scores.each do |name, score|
  p "#{name}: #{score}"
end
  • whileと同じ様に1行で表現する場合は、do-endを波かっこで表現も可能。
  • doの省略は不可。

times

  • 回数が決まっている際に利用する。
  • 数字クラスのメソッド
10.times do |i|
  puts "#{i}: hello"
end

10.times { |i|
  puts "#{i}: hellohello}"
}
  • doの後ろにブロックパラメーターを準備できる。
    • |i|
  • doは省略可能。

無限ループ

  • loop do-end

繰り返しで使える命令

  • ループ終了
    • break
  • ループスキップ
    • skip

メソッド

  • 本来はクラスに定義するもの
  • グローバルに直接定義する事も可能
    • privateとなる。
def sayHello
    p "hello"
end

sayHello # hello
  • def-endで囲う
  • ()で引数を渡す事も可能
    • =で初期化も可能
    • 実行側の()は省略可能。
  • returnを使わなくても、最後の値を返す様になる。

クラス

  • クラスは大文字から始まる
  • インスタンス化
    • tom = User.new
  • イニシャライズ
    • def initialize()-end
  • インスタンス変数
    • @variable
    • クラス内部のどこからでも参照可能
    • メソッド内でのみ定義可能

アクセサ

  • インスタンス変数には直接アクセスできない
    • すべてprivate
  • getter/setterの為のショートハンド

    • アクセサ
      • attr_accessor <Symbol>
        • setterとgetterを作ってくれる
    • getterのみ定義
      • attr_reader <Symbol>
  • self

    • レシーバを指す
    • クラスメソッド内で利用可能
      • レシーバである事に注意。
        • attr_accessorやattr_readerを付与していれば呼び出せる
    • selfは曖昧な表現にならない限り省略可能である。
  • レシーバ

    • メソッドを受け取っている(インスタンス)の事。
class User

  attr_reader :name

  def initialize(name="noName")
    @name = name
  end

  def sayHi
    # @<var>でインスタンス変数にアクセス
    #   return "Hi, #{@name}"
    # selfでレシーバにアクセス
    # return "Hi, #{self.name}"
    # selfは曖昧にならない限り省略可能
    return "Hi, #{name}"
  end
end

クラス変数・クラスメソッド・クラス定数

  • クラス変数は@@で定義する
  • クラスメソッドはメソッド名にselfをつける
    • ```Class.で呼び出し可能
    • 関数名の先頭にselfをつけると、クラスメソッドの作成となる。
  • クラス定数は全て大文字で宣言する
    • Class::<CONST>で呼び出し可能
class User

  attr_reader :name

  # クラス変数を定義する。
  # クラス変数は直接呼び出せない
  @@count = 0
  # 定数を宣言する。
  VERSION = 1.1

  def initialize(name="noName")
    @name = name
    # インスタンス化される度にクラス変数を1増加する。
    @@count += 1
  end

  def sayHi
    return "Hi, #{name}"
  end

  # クラスメソッドを定義する。
  def self.info
    p "hi, i am UserClass, #{@@count} Version: #{VERSION}"
  end
end

# クラスメソッドの呼び出し
User.info
# クラス定数の呼び出し
p User::VERSION

クラスの継承

class AdminUser < User
  def sayHello
    puts "Hello from #{name}"
  end
end

tom = AdminUser.new("TOM")

p tom.sayHi
tom.sayHello
  • <で継承でできる
  • オーバーライド可能

メソッドのアクセス権

  • 原則はpublic
  • initializeとクラスの外に書いたメソッドはprivateになる。
  • privateはクラスの中で定義して、クラスのメソッド内部で利用する。
    • privateメソッドはself指定なしで呼び出す。
      • privateメソッドはselfが使えない為
    • Rubyのprivateメソッドはオーバーライドが可能である。
class User

  attr_reader :name

  def initialize(name="noName")
    @name = name
  end

  private def sayPrivate
    puts "private"
  end

  def sayHi
    sayPrivate
    p "Hi, #{@name}"
  end

end

class AdminUser < User
  def sayHello
    sayPrivate
    puts "Hello from #{name}"
  end
end

tom = User.new("TOM")
tom.sayHi

モジュール

  • 継承不可
  • インスタンス不可
  • 用途2つ
    • 名前空間を作成する。
    • MIX-INを提供する。
  • モジュールの1文字目は大文字
  • モジュール変数 = 定数
    • 普通の定数と同じ様に呼び出す。
  • モジュール関数を作成できる
    • <ModuleName>.<method>
    • def self.<method> - end
# module
# クラス・メソッドOK
# インスタンス化できない・継承できない
# 用途 -> 名前空間

module Movie

  VERSION = 1.1

  def self.encode
    puts "encoding"
  end

  def self.export
    puts "export"
  end
end

Movie.export
p Movie::VERSION

Mix-In

  • モジュールの2つ目の役割
  • 用途の違うクラスに共通の機能を付与する
  • インスタンスメソッドとして定義する。
    • 他のクラスのインスタンスに埋め込む事ができる。
  • include命令を利用して、MIX-INを行う。
# デバッグ機能を各クラスに追加したい

module Debug
  def info
    puts "#{self.class} debug info..."
  end
end

class Player
  include Debug
end

class Monster
  include Debug
end

player = Player.new

player.info

monaster = Monster.new

monaster.info

例外

  • begin-rescue-endでtry-catch
  • ensureで成功でもエラーでも行う処理を記述できる
  • raiseで独自のエラークラスを引数に取り、エラーを発生させる事ができる。
    • 独自エラークラスは、StandardErrorクラスを継承する事
class MyError < StandardError
end

x = gets.to_i

begin
  if x == 3
    raise MyError
  end
  p 100 / x
rescue MyError
  puts "this is myError"
rescue => ex
  p ex.message
  p ex.class
  p "stopeed"
ensure
  p "--end--"
end

まとめ

やっぱりRubyの文法は好きです。
(GitHub社が好きな理由がよく分かる。)

次回はRails5.0で簡単アプリでも作りたいと思います。

tfrcm
React / ReactNative / Go / TypeScript / AWS / Docker / k8s
https://gemcook.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした