#この記事について
初学者による、Ruby基礎文法入門の、学習内容アウトプット・自身の振り返り用メモです。
楽しくメモするために、値が大体焼肉です。
参考資料
Progate Ruby学習コース
ドットインストール Ruby入門
【文字列】
文字列
- 「"」:特殊文字、式展開を使える
- 「'」:値がそのまま出力される
- 「\n」:改行
- 「\t」:タブを表示
- 「* 数値」:数値回数表示する
文字列学習時に出てきたメソッド
price.upcase # 文字列を大文字で返す
price.upcase! # 文字列を大文字で返しつつ、元の文字列も大文字に書き換える
price.reberse # 文字列を逆順に返す
price.emyty? # 文字列が空かどうか調べる
price.include?("t") # 特定の文字が含まれているか調べる
#【数値】
p 10 + 3 # 13
p 10 * 3 # 30
p 2.4 * 2 # 4.8
p 10 / 3 # 3
p 10.0 / 3 # 3.33333...(小数点以下を表示)
p 10 % 3 # 1
p Rational(2, 5) + Rational(3, 4) #(分数 23/20)
p 2/5r + 3/4r #(分数Rationalの省略系)
p 52.6.round # 四捨五入
p 52.6.floor # 小数点以下切り捨て ふろあ
p 52.6.ceil # 小数点以下切り上げ すぃーる
#【コメント】
- 行の先頭に「#」を書くと、その行がコメントになる
- =begin〜=endで囲った行は全てコメントになる
# 焼肉食べてないのでインスタンス変数あたりから理解が乏しい
=begin
なので冷静に情報を整理したり、他記事を参考に
理解を深める、もしくは焼肉を食べry
=end
#【出力の違い】
「p」はダブルクォーテーションで囲まれて表示される
複雑な構造の場合にこれは文字列だと分かりやすいよう表示してくれる
print "Do you like Yakiniku?" #改行なしで出力
puts "Do you like Yakiniku?" #改行ありで出力
p "Do you like Yakiniku?" #デバッグ用
#【変換】
数値と文字変換
p 29 + "29".to_i # 整数に変換「too integer」 to_i
p 29 + "29".to_f # 浮動小数点数に変換「to float」 to_f
p 29.to_s + "29" # 文字列に返還「String」 to_s
ハッシュと配列の返還
# t_a (to Array) ハッシュを配列に変換
# to_ #h(to Hash) 配列をハッシュに変換
price = {上タン: 1800, 上ハラミ: 1500}
p price.to_a.to_h
#【%記法】
puts %Q(hello) #""で囲った文字列を表現
puts %(hello) #上記のQは省略可能
puts %q(hello) #''で囲った文字列を表現
なぜ%記法を使うのか?
「""」や「''」の中で、" 'を使いたい場合
区切り文字ではないという意味で「\」をつける必要があるが
%記法は必要はなく、見やすい場合がある
puts "he\"llo" puts %(hello)
puts 'he\'llo' puts %q(hello)
配列で文字列を管理したい場合の%記法
値を多く書くのが場合はこういう書き方もできる
p ["red", "blue"] p %W(red blue)
p ['red', 'blue'] p %w(red blue)
#【書式付きで文字列に値を埋め込む】
"文字列" % 値
書式付きでいろいろな値を表示する
- %s:文字列
- %d:整数
- %f:浮動小数点数
文字列
p "name: %s" % "熟成カルビ"
p "name: %10s" % "熟成カルビ" # 10桁分の幅を確保
p "name: %-10" % "熟成カルビ" # 10桁分を確保+左寄せ
数値
p "id: %05d, rate: %10.2f" % [29, 2,929]
# 値が複数の場合は配列で渡す
# idは整数、rateは浮動小数点数の場合
# idは5桁にしたいが、5桁に満たない場合は0で埋める
# rateは少数点の前が10桁、小数点以下が2桁
printf/Sprintf
printf
書式付きで文字列を表示するための命令
printf("name: %10s\n", "taguchi")
printf("id: %05d, rate: %10.2f\n", 355, 3.284)
Sprintf
表示するのではなく文字列を返してくれる命令
文字列が帰ってくるのでそれをpで表示
p sprintf("name: %10s\n", "taguchi")
p sprintf("id: %05d, rate: %10.2f\n", 355, 3.284)
#【配列】
colors = ["red", "blue", "yellow"]
p colors[0] # 添字(0からスタート)を出力
p colors[-1] # 末尾から数えた添字(末尾が1)を出力
p colors[0..2] # 0から2を出力
p colors[0...2] # 0から1(2の直前まで)を出力
p colors[5] # nil(何もない)
colors[0] = "pink" # 指定した添字の値を変更
colors[1..2] = ["white", "black"] # 指定した番号をまとめて変更
colors.push("gold") # 末尾に値を追加
colors << "silver" # 末尾に値を追加する省略形
配列学習時に出てきたメソッド
p colors.size # 要素の数を示す
p colors.sort # 要素の並び替えをしてくれる
#【ハッシュ】
キーと値をペアにして複数の値をまとめて管理する方法(オブジェクト)
配列とハッシュの違い
配列 :複数の値を並べて管理
ハッシュ :それぞれの値にキーと呼ばれる名前をつけて管理
配列は要素を[ ]で囲むが、ハッシュは{ }で囲む
{キー1 => 値1, キー2 => 値2}
キーと値の間は「=>」でつなぐ
配列と同様に、要素と要素はコンマ(,)で区切る
prices = {"bibimbap" => 800, "gukbap" => 700}
シンボルオブジェクト
:から始まる識別子のようなオブジェクト
キーは「シンボルオブジェクト」がよく使われる
文字列を使うより、動作が高速でRubyではよく使われる
prices = {:bibimbap => 800, :gukbap => 700}
上記のシンボルを使ったハッシュはよく使う為、短い記法がある
prices = {bibimbap: 800, gukbap:700}
ハッシュ各要素へのアクセスは配列と同じ
p prices[:bibimbap] # シンボルを使う
ハッシュの要素を更新
prises[:bibimbap] = 900 # 更新
ハッシュの要素を追加
ハッシュ[新しいキー] = 値と書くことで要素を追加
既にあるキーを指定すると、要素の追加ではなく更新になるので注意
prices[:Namul] = 650 # 追加
ハッシュ学習時に出てきたメソッド
p prices.size # 要素の数を引っ張ってくるメソッド
p prices.keys # キーの一覧を引っ張ってくるメソッド
p prices.values # 値の一覧を引っ張ってくるメソッド
p prices.has_key?(:gukbap) # そのキーがあるか調べるメソッド
#【条件分岐】
ユーザーから入力を受け付ける命令・メソッド「gets」
price = gets.to_i #数値に変換する場合to_i
signal = gets.chomp
# getsは一行読み込むが最後に改行コードがついている
# chompというメソッドでその最後の改行コードを取り除く
if
if money > 15000
puts "焼肉おごりますよ!"
elsif money > 7000
puts "焼肉行きましょう!"
else
puts "焼肉が食べたい..."
end
単純な条件分岐の場合はifを後ろに書くこともできる
puts "焼肉おごりますよ!" if money > 15000
case
値に応じて何らかのメッセージを出し分けたい時の処理
下記はifで実現できるが、caseを使うとすっきり書ける場合もある
case meat
when "カルビ"
puts "上カルビにしましょ!"
when "ロース", "ハラミ" #コンマで区切って並べることもできる
puts "上にしましょ!"
when "上タン塩"
puts "タンしか勝たん"
else
puts "タンは絶対オーダーしましょう!"
#【繰り返し処理】
使い分け
- whileは条件
- timesは指定した数
- for(each)は要素の数
while
i= 0 #iを0で初期化
while i < 10 do #10未満で繰り返す
puts "#{i}: I want to eat yakiniku"
i += 1
end
time
繰り返しの回数が決まっている場合に便利
doからendの中に行いたい処理を書く
10.times do |i|
puts "#{i}: I want to eat yakiniku"
end
# 何回目のループかを知りたい時はdoの後ろに|変数|
doからendの間の処理が一行しかないときは{ }で代替できる
10.time { |i| puts "#{i}: hello" }
for
forでは何らかの集合的なオブジェクト(配列やハッシュ)
また、範囲を表すオブジェクトの要素数分だけを
何らかの処理を繰り返すことができる命令
for i in 15..29 do #doは省略可能
p i
end
# 配列
for meat in ["tongue", "offal"] do
p meat
end
# ハッシュ
for meat, price in {tongue:1000, offal:800} do
p "#{meat}: #{price}"
end
each
forは内部的にはeachというメソッドを使っている為
forはeachを使って書き換えることができる
timeメソッド同様に、繰り返す処理が一行ぐらいであれば
doからendを{ }で囲って一行で表現することも可能
(15..29).each do |i|
p i
end
配列
["tongue", "offal"].each do |meat|
p meat
end
ハッシュ
{tongue:1000, offal:800}.each do |meat, price|
p "#{meat}: #{price}"
end
loop
i = 0
loop do
p i
i += 1
end
永久にループする処理はループを抜ける命令とよく一緒に使われる
break
10.times do |i|
if i == 7
break #7の直前でループを抜ける
end
p i
end
next
10.times do |i|
if i == 7
next #7を1回スキップする
end
p i
end
break,nextは
loop含む、whileやforやtimesなどの繰り返し処理の中で使える
#【メソッド】
複数の処理を1つにまとめたもの
メソッドの利点
メソッドを用いない場合は何度も同じような処理を書く必要があるが
共通の処理をメソッドにまとめることによって、シンプルに書くことができる
# メソッドを用いない場合
puts "こんばんは"
puts "私はカルビ王子です"
puts "こんばんは"
puts "私はタン先生です"
puts "こんばんは"
puts "私はハラミ大臣です"
# メソッドを用いた場合
def introduce(name)
puts "こんにちは"
puts "私は#{name}です"
end
introduce("カルビ王子")
introduce("タン先生")
introduce("ハラミ大臣")
メソッドの定義
「def メソッド名」と「end」の間にまとめたい処理を書く
このことを「メソッドを定義する」と言う
右の図では、2つの出力を行う、introduceメソッドを定義しています。
書式
def メソッド名
処理
end
def introduce
puts "こんにちは"
puts "私が焼肉です"
end
introduce #introduceメソッドを呼び出し
#【引数】
引数を受け取るメソッドの定義・呼び出し
書式
def メソッド名(引数名)
処理
end
メソッド名(値) # メソッドの呼び出し + 値が引数に代入
メソッド内で引数を使用する
def introduce(name)
puts "こんばんは"
puts "私が#{name}です" # 引数はメソッド内で変数のように使える
end
introduce("焼肉のお兄さん")
引数のあるメソッドは、引数を渡さずに呼び出すことができない
エラーになるので注意
複数の因数を受け取る・呼び出す
def meat(name, price) # 左から第1引数、第2引数
puts "#{name}"
puts "#{price}円"
end
meat("豚トロ", 800)
#【戻り値】
戻り値のあるメソッド
メソッドの中でreturnを使うと、呼び出し元で値を受け取れる
「return 値」と書くことで、メソッドはその値を戻り値として返します。
書式
def メソッド名
return 値 #呼び出し元に値を返す(=戻り値)
end
def add(a,b)
return a + b # aとbを足した値が戻り値として呼び出される
end
戻り値を受け取る
戻り値がある場合、メソッドの呼び出し部分がそのまま戻り値に置き換わる
ソッドの呼び出し部分を変数に代入するように書くことで
メソッドの戻り値を受け取ることができます。
def add(a,b)
return a + b
end
sum = add(1,3) # 呼び出し部分
puts sum # 出力 4
様々な戻り値
戻り値も引数と同様に、様々な値を用いることができる
if文で使うような条件式をreturnすると、
その条件式の結果として得られる真偽値(trueまたはfalse)を返すことができる
真偽値を返すメソッドは、メソッド名の末尾に「?」をつける慣習があり
def meat_free?(price)
return price >= 10000
end
if meat_free?(14000)
puts "次回御来店の際は上タン塩サービス"
else
puts "次回御来店の際はキムチサービス"
end
returnによる処理の終了
returnは戻り値を返すだけでなく、メソッドの処理を終了させる性質も持つ
よって、returnの後にあるメソッドの処理は実行されない
def add(a, b)
return a + b # ここで処理が終了する
puts "計算しました" #実行されない
end
複数のreturn
メソッドでは、条件分岐を組み合わせることで
複数のreturnを用いることができる
def price_with_shipping(price)
if price >= 10000
return price
end
return price + 500
end
puts "合計金額は3000円です"
puts "お支払い金額は、持帰り肉込みで#{price_with_shipping(8000)}円です"
# 8500円で出力
puts "商品の合計金額は10000円です"
puts "お支払い金額は、送料込みで#{price_with_shipping(10000)}円です"
# 10000円で出力
#【キーワード引数】
引数の数が多くなると、呼び出し側で値がどの引数に入るのか分かりにくい
キーワード引数を用いることで、呼び出し側で引数を明記することができる
通常のメソッドの書き方に加えて
1.定義側で、引数の後にコロンを付ける
2.呼び出し側で、値の前に引数名を書く
とすることで、キーワード引数を持つメソッドを書くことができる
# 今までの書き方
def introduce(name, age, food)
puts "私は#{name}です"
puts "年齢は#{nage}歳です"
puts "好きな食べ物は#{food}です"
end
introduce("焼肉のお兄さん", 37, "焼肉")
# それぞれの値がどの引数に入るのかわかりにくい
# キーワード引数を用いた書き方
def introduce(name:, age:, food:) #コロンつける
puts "私は#{name}です"
puts "年齢は#{nage}歳です"
puts "好きな食べ物は#{food}です"
end
introduce(name:"焼肉のお兄さん", age:37, food:"焼肉")
#呼び出した時に引数名を明記した書き方
#【クラス】
- 設計図:クラス
- もの:インスタンス
クラスは設計図のようなもの
その設計図からつくる実際の「もの」にあたるものがインスタンス
インスタンスが持つ情報である「インスタンス変数」と
インスタンスに対して呼び出す「インスタンスメソッド」は
クラスの中で定義する
インスタンスを生成するSTEP
STEP1 クラスを用意する
STEP2 クラスからインスタンスを生成する
STEP3 インスタンスに情報を追加する
クラスの定義
クラスは「class クラス名」とすることで定義できる
クラス名は必ず「大文字」で始め + 「end」を書く必要がある
class Menu # クラス名は大文字で始める
end # endを忘れずに
インスタンス変数
attr_accessor
情報を持たせるには、「attr_accessor シンボル」とする
Menuクラスのインスタンスにnameという情報を持たせることができる
また、この「name」という情報のことを「インスタンス変数」と呼ぶ
class Menu
attr_accessor :name
end
#Menuクラスのインスタンスにnameという情報をもたせることができる
#このnameという情報のことを、インスタンス変数と呼ぶ
インスタンスの生成
クラス(設計図)を元に新しくインスタンスを生成するには「クラス名.new」
また「変数名 = クラス名.new」で生成したインスタンスを変数に代入できる
インスタンス変数に値を代入
インスタンスに情報をもたせるには、クラスで用意した
インスタンス変数に値を代入する必要がある
具体的には「インスタンス.変数名 = 値」とすることで
そのインスタンス変数に値をセットすることができる
class Menu
attr_accessor :name
attr_accessor :price
end
menu1 = Menu.new
menu1.name = "シャトーブリアン" #シャトーブリアンを代入
puts menu1.name #出力 シャトーブリアン
#【インスタンスメソッド】
クラスの中でメソッドを定義・呼び出し
クラスの中で定義したメソッドは、インスタンスに対して使うようにして呼び出す
具体的には「インスタンス.メソッド名」のようにすることで
そのメソッドを呼び出すことができる=インスタンスメソッド
class Menu
attr_accessor :name
attr_accessor :price
def show
puts "私はお肉です"
end
end
menu1 = Menu.new
menu1.show #インスタンス.メソッド名で呼び出し
インスタンスメソッドも、引数を受け取ったり戻り値を返すことができる
class Menu
|
def show(data) # 引数
return "私は#{data}です" # 戻り値
end
end
menu1 = Menu.new
puts menu1.show("お肉")
インスタンスメソッドの中でインスタンス変数を扱う
インスタンスメソッドの中では「self」を用いて「self.変数名」とすることで
インスタンス変数を扱うことができる
インスタンスメソッドでは変数「self」に
呼び出したインスタンス自身が代入されている
class Menu
|
def show_name
puts "私は#{self.name}です"
end
end
menu1 = Menu.new
menu1.name = にんにく
menu1.show_name # インスタンスメソッドの呼び出し
####initializeメソッド
インスタンスを生成した直後に処理を実行することができる
「クラス名.new」でインスタンスを生成した直後に自動で呼び出される
initializeメソッドは、他のインスタンスメソッドと同じように定義できる
下記は、「Menu.new」でMenuインスタンスが生成された直後に
initializeメソッドが呼び出され、その中の処理が実行されている
class Menu
|
def initialize
puts "メニューが生成されました"
end
|
end
menu1 = Menu.new
# Menu.newが実行されると自動でinitializeメソッドが呼び出される
initializeメソッドでインスタンス変数を扱う
インスタンスメソッドの中では「self.変数名」でインスタンス変数を扱える為
「self.変数名 = 値」でインスタンス変数に値を代入できる
class Menu
|
def initialize
self.name = "マルチョウ"
end
|
end
menu1 = Menu.new
puts menu1.name
# インスタンス生成直後に"マルチョウ"をインスタンス変数nameに代入
initializeメソッドの引数
initializeメソッドは通常のインスタンスメソッドと同じように引数を渡せる
その際「クラス.new」に対して引数を渡すことで
initializeメソッドにその値を渡すことができる
class Menu
|
def initialize(message) # 肉は一度しか裏返しませんが渡ってくる
puts message
end
|
end
menu1 = Menu.new("肉は一度しか裏返しません")
initializeメソッドでインスタンス変数に値を代入
initializeメソッドでインスタンス変数に引数の値を代入することで
インスタンスごとにインスタンス変数の値を変えることができる
その際に、キーワード引数を使うことで見やすく書ける
class Menu
|
def initialize(name:, price:)
self.name = name
self.price = price
end
|
end
menu1 = Menu.new(name: "マルチョウ", price: 800)
#【ファイルの分割】
(分割時の例)
index.rbからMenuクラスの定義をmenu.rbに移動させたら
menu.rbのコードをindex.rbでも使えるようにする
index.rbの一番上の行で「require "./menu"」とすることで
menu.rbのコードを読み込めるようになる
# index.rb
require "./menu"
menu1 = Menu.new(name: "ハツ", ・・・)
|
Menuクラスから生成したインスタンスも、配列の要素にすることが可能
各インスタンスを要素とする配列を変数menusに代入し
その配列に対してeach文を用いることで各メニューを表示してみた場合が下記
# index.rb
menu1 = Menu.new(name: "ハツ", price: 900)
menu2 = Menu.new(name: "レバー", price: 800)
|
menus = [menu1, menu2, ....]
menus.each do |menu| # each文を用いて、1つずつメニューを表示
puts menu.info
end
#【継承】
あるクラスを元にして新たなクラスをつくることを「継承」と呼ぶ
「class 新しいクラス名 < 元となるクラス名」とすることで
他のクラスを継承して、新しいクラスを定義できる
新しいクラスは「子クラス」
元となるクラスは「親クラス」
require "./menu"
class Food < Menu
end
子クラスのインスタンス
子クラスは親クラスのインスタンス変数とインスタンスメソッドを引き継ぐ
下記例のようにFoodクラスのインスタンスは
Menuクラスのインスタンス変数やインスタンスメソッドを呼び出すことが出来る
# index.rb
food1 = Food.new(name: "アカセン", price: 900)
puts food1.name
puts food1.info
# menu.rb
class Menu
attr_accessor :name
|
def info
return "#{self.name} #{self.price}円"
end
end
子クラスにインスタンス変数を追加する
子クラスにインスタンス変数を追加には通常通り「attr_accessor」を用いる
下記のFoodクラスはMenuクラスを継承しているので
・name ・price ・calorie
の3つのインスタンス変数を用いることができる
# index.rb
food1 = Food.new(name: "アカセン", price: 900)
puts food1.name
puts food1.info
# menu.rb
class Menu
attr_accessor :name
attr_accessor :price
|
end
# food.rb
class Food < Menu
attr_accessor :calorie # Foodクラスには「calorie」を追加
end
オーバーライド
親クラスにあるメソッドと同じ名前のメソッドを子クラスで定義すると
メソッドを上書きすることができる = 「オーバーライド」
オーバーライドをすると、子クラスのインスタンスは親クラスのメソッドではなく、
子クラスで定義したメソッドを呼び出すようになる
(オーバーライドの仕組み)
子クラスのインスタンスは、子クラスで定義したメソッドを優先して呼び出す
したがって、子クラスと親クラスに同名のメソッドがある場合は
子クラスのメソッドを呼び出すので、結果的にメソッドの内容が上書きされたようになる
super
オーバーライドしたメソッドの中で「super」とすることで、
親クラスの同名のメソッドを呼び出すことができる
あくまでメソッドを呼び出しているので、
親クラスのメソッドの定義に合わせて、superに対して引数を渡す必要がある
# menu.rb
class Menu
attr_accessor :name
attr_accessor :price
def initialize(name:, price:)
self.name = name
self.price = price
end
|
end
# food.rb
class Food < Menu
attr_accessor :calorie
def initialize(name:, price:, calorie:)
super(name: name, price: price) # 親クラスの同名メソッドを呼び出す
self.calorie = calorie
end
|
end
#【データクラス】
Dateクラス = 日付を扱うクラス
DateクラスはRubyがすでに用意しているクラスで
requireを用いて読み込むことで、自分でクラスを定義しなくても使うことができる
(すでに用意されているクラスは、requireの書き方が少し異なるので注意)
require "date"
# "./date"ではないことに注意
Dateクラスのインスタンス
Dateクラスは今まで扱ってきたクラスと同様に
Date.newとすることでインスタンスを生成できる
Dateクラスのインスタンスをputsすると
下記のようにその日付を表示できる
reequire "date"
date1 = Date.new(2020,12,18) # 引数に「年月日」を渡してDateインスタンスを生成
puts date1
# 出力 2014-07-31
今日の日付のDateインスタンスを取得
Dateクラスでは、Date.todayとすることで、
今日の日付のインスタンスを作ることができる
require "date"
date1 = Date.today
puts date1
#【クラスメソッド】
クラスメソッドは、「def クラス名.メソッド名」とすることで定義できる
インスタンスメソッドとの違いはメソッド名の前にクラス名を書く必要がある点
下記はMenuクラスに、「is_discount_day?」というクラスメソッドを定義
クラスメソッドは定義時と同じように、
「クラス名.メソッド名」とすることで呼び出すことができる
定義
def クラス名. メソッド名
# 処理
end
例
class Menu
|
def Menu.is_discount_day?
# 処理
end
end
puts Menu.is_discount_day?
インスタンスメソッドとクラスメソッドの復習
インスタンスに対して呼び出すメソッドは「インスタンスメソッド」
クラスに対して呼び出すメソッドは「クラスメソッド」
class Menu
|
def info # インスタンスメソッドの定義
end
end
menu1 = Menu.new
menu1.info # インスタンスメソッドは、インスタンスに対して呼び出す
class Menu
def Menu.is_discount_day? # クラスメソッドの定義
end
end
Menu.is_discount_day? # クラスメソッドは、クラスに対して呼び出す