Open19
Ruby攻略
Rubyプログラム実行方法
- irb(Interactive Ruby)を利用
- ファイルに保存したプログラムの実行
Ruby基礎
コメント
# コメント
変数(ローカル変数)
変数名 = 式
name = 'Tooyama'
命名規則
- アルファベットの小文字 (a...z)or アンダースコア(_)で始まる
- それに続けてアルファベット、数字、アンダースコアで記述
- マジックナンバーを原則やめる(例 price1 など)
- _を最初につけるのは意図してつけるとき以外はやめる
定数
- 大文字で書く
- 再代入を行わない
TAX = 1.08
TAX_RATE = 1.08
単語理解
オブジェクト指向プログラミング言語
- コンピュータ・プログラミングの概念の一つ
- オブジェクト指向の概念や手法を取り入れたもの
- プログラムを、データとその振る舞いが結びつけられたオブジェクトの集まりとして構成する
オブジェクト指向
- オブジェクト同士が相互に関係し合うことで、システムの振る舞いをとらえる考え方
クラス
- オブジェクトの設計図
インスタンス
- クラス(設計図)から作成した、実態
メソッド
- クラスの中に定義されているもので、複数の処理を一つにまとめて、扱いやすくしたもの
- クラスに所属する関数のようなもの
Rubyの=== 演算子について
- javascriptよりもフレキシブ!
場合 | 説明 |
---|---|
左辺が単独のStringやIntegerオブジェクト | ==と同じ動作 |
左辺がClassオブジェクト | 右辺がそのクラスのインスタンスであるかどうかを比較する |
左辺がRegexpオブジェクト | 右辺とマッチするかどうかを取れる |
演算子の優先順位
インクリメント, デクリメント
# n++, n--ができない
n += 1
n -= 1
条件分岐
構文:if
ポイントはelse ifではなく、elsif!
if 条件1
# 条件1の処理
elsif 条件2
# 条件2の処理
elsif 条件3
# 条件3の処理
else
# それ以外の処理
end
構文:unless
- ifの逆
- ポイントはelsifに相当するものはない
unless 条件式
# 条件式が偽(false)のとき、実行したい処理
else
# 条件式が真(true)のとき、実行したい処理
end
構文:case
case 対象のオブジェクトや式
when 値1
# 値1に一致する場合の処理
when 値2
# 値2に一致する場合の処理
when 値3
# 値3に一致する場合の処理
else
# どの値とも一致しない場合の処理
end
メソッド
def メソッド名 (引数1, 引数2 ...)
#実行したい処理
end
メソッド命名規則
- 小文字の英数で書く(hello)
- スネークケース(hello_world)
- マジックナンバーを基本的にはやめる(hello1)
- 日本語のメソッド名はトラブルを避けるためやめる
戻り値
- Rubyでは最後に評価された式が戻り値となる
def add(x, y)
x + y
# return x + y
end
add(10, 1) # 11
出力方法
puts
- 改行される
- 戻り値はnil
puts 'Hello'
# Hello
# => nil
- 改行されない
- 戻り値はnil
puts 'Hello'
# Hello => nil
p
- 戻り値は引数のオブジェクト
- デバック用に使う
p 'Hello'
# => Hello
pp
- 戻り値は引数のオブジェクト
- デバック用に使う
- 適切なインデントと改行で整形される
p 'Hello'
# => Hello
配列操作
下記の通り、配列a, b, cを定義します。
a = [ ]
b = [ 'a', 'b' ]
c = [1, 2, 2, 3, 5, 5]
配列が空ではないことを確認する方法(empty)
a.empty? # true
ある要素が存在するか(include)
a.include?('a') # false
b.include?('a') # true
配列を反転(reverse)
b.reverse # [ 'b', 'a' ]
b.reverse! # 破壊的メソッド(b自体が[ 'b', 'a' ]に変わってしまう)
シャッフル(shuffle)
b.shuffle # ["b", "a"]
0~25の要素を持つ配列を作成
- 範囲オブジェクト(0..25)
(0..25).to_a
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
配列の末尾に追加(<< , push)
# パターン①
b << 'c'
# パターン②
b.push(' c ')
配列の末尾を削除(pop)
b.pop
# 'b'
puts b
# ['a']
配列の重複を削除(uniq)
c.uniq
# [1, 2, 3, 5]
配列要素の結合(join)
s = ["my", "name", "is", "tooyama"]
s.join(' ')
# my name is tooyama
配列要素の個数を求める(size)
c.size
# 6
# cは[1, 2, 2, 3, 5, 5]なので6
to_〇〇メソッド
オブジェクトの種類を変換するメソッド
to_s(文字列型に変換)
num = 1
num.to_s
# => " 1 "
to_i(数値オブジェクトに変換)
# オブジェクト.to_i
num = " 1 "
num.to_i
# => 1
to_f(Floatクラス(浮動小数点数)に変換)
# 整数.to_f
num = 1
num.to _f
# => 1.0
to_sym(シンボルに変換)
# 文字列オブジェクト.to_sym
"hoge".to_sym
# => :hoge
to_h(ハッシュオブジェクトに変換)
# 二次元配列オブジェクト.to_h
human = [["name", "tooyama"], ["age", 21]]
human.to_h
# => {"name"=>"tooyama", "age"=>21}
to_a(ハッシュ、範囲オブジェクトなどを配列に変換)
(0..25).to_a
# => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
human = {name: "tooyama", "age" => 21}
human.to_a
# => [[:name, "tooyama"], ["age", 21]]
ハッシュ
{ キー1 => 値1, キー2 => 値2 }
keyに文字列を使ったハッシュ
# 初期値
tooyama = {'name' => 'Tooyama', 'age' => 21}
# 追加
tooyama['favorite'] = 'sports'
# 出力
tooyama['name']
# => Tooyama
# 変更
tooyama['age'] = 22
# 削除
tooyama.delete('age')
keyにシンボルを使ったハッシュ
シンボルとは
- ソースコード上では文字列のように見えるが、内部では整数として扱われる
- シンボルを使ったキーの方が、文字列をキーに使う場合に比べて、Hashのアクセスは早いとされている
# 初期値(この書き方の方が馴染みがある)
tooyama = { name: 'Tooyama', age: 21 }
# 追加
tooyama[:favorite] = 'sports'
# 出力
tooyama[:name]
# => Tooyama
# 変更
tooyama[:age] = 22
# 削除
tooyama.delete(:age)
ハッシュ内要素の存在を確認
# キーの確認
tooyama.keys
# => [:name, :age]
# バリューの確認
tooyama.values
# => ["Tooyama", 22]
# キーの存在を確認
tooyama.has_key?(:name)
# => true
# サイズの確認
tooyama.size
# => 2
繰り返し処理
繰り返し処理を行いたい時に使う
- each
- for
- times
- while
- upto, downto
- step
- loop, break, next
each
- 最初から最後まで順番に取り出しながら処理を実行
配列やハッシュ.each do |変数|
# 繰り返し実行したい処理
end
# ハッシュで使う場合
scores = { taka: 100, tarou: 90}
scores.each do |k, v| # k = key, v = value
puts v
# 100
# 90
end
for
for 変数 in 配列やハッシュ do
# 繰り返し実行したい処理
end
times
- 配列を使わずに、単純にn回処理を繰り返したい場合は、Integerクラスのtimesメソッドを使うと便利
- n回この処理繰り返したいー
繰り返し回数.times do |i|
# 繰り返し実行したい処理
end
5.times do |i|
puts "#{i}. Hello"
# 0. Hello
# 1. Hello
# ...
end
while
指定した条件が真(true)である時に処理を繰り返す
while 条件式 do
# 繰り返し実行したい処理
end
upto, downto
- nからmまで数値を1づつ増やしながら何かしらの処理を実行したい場合に使う
- downtoはuptoの逆
開始値.upto(終了値) { 繰り返し実行したい処理 }
10.upto(14) { |n| puts n }
# 10
# 11
# ...
# 14
step
- nからmまでxずつ値を増やしながら、何かしらの処理を実行したい時に利用
- 例 1, 3, 5, 7, 9
開始値.step(上限値, 一度に増減する大きさ) { 繰り返し実行したい処理 }
1.step(10, 2) { |n| puts n }
# 1, 3, 5, 7, 9
loop, break
あえて無原ループを作りたい時に使う
loop do
# 繰り返し実行したい処理
end
# break()
loop do
i += 1
break if i == 10
end
next(次の処理に進みたい場合)
# 奇数の時のsh
numbers = [1, 2, 3, 4, 5]
numbers.each do |numer|
next if n % 2 == 0 # n.even?でも同じ処理
puts n
end
クラス
# クラス作成
class Car
# クラスのインスタンスは変数を使って値を保持できる
# initializeはnewを使われてた時に呼ばれる特殊なメソッド
def initialize(name)
# @name = インスタンス変数(インスタンス内ならどこでも使える)
@name = name
end
def hello
puts 'hello'
end
end
# インスタンス作成
car = Car.new
# メソッド呼び出し
car.hello
# initializeが最初に呼ばれる
car = Car.new('Kitt')
アクセサメソッド
- attr_accessorメソッド(attr = attribute)
- インスタンス変数の値を読み書きするメソッド
- インスタンスメソッドを開発者が書かなくても良くなる
インスタンスメソッドを開発者が書いた場合
class Car
def initialize(name)
@name = name
end
# インスタンス変数@nameを、クラスの外部から参照したい!(getter)
def name
@name
end
# インスタンス変数@nameの値を、クラスの外部から書き換えたい(setter)
def name=(value)
@name = value
end
end
car = Car.new('Kitt')
# car.@name NG(参照できない)
puts car.name
# Kitt
puts car.name = 'Tooyama'
# Tooyama
アクセサメソッドを使った場合
class Car
attr_accessor :name
def initialize(name)
@name = name
end
end
car = Car.new('Kitt')
car.name # OK
car.name = 'Tooyama' # OK
アクセサメソッドを使って読み込みを行いたい場合
class Car
attr_reader :name
def initialize(name)
@name = name
end
end
car = Car.new('Kitt')
car.name # OK
car.name = 'Tooyama' # NG
アクセサメソッドを使って書き込みだけを行いたい場合
class Car
attr_writer :name
def initialize(name)
@name = name
end
end
car = Car.new('Kitt')
car.name # NG
car.name = 'Tooyama' # OK
クラス変数
クラス自体に値を保持できる変数
class Car
# initializeメソッドが何回呼ばれたか
@@count = 0
def initialize(name)
@name = name
@@count += 1
end
def hello
puts "Hello! #{@@count} instance(s)"
end
end
kitt = Car.new('Kitt')
kitt.hello
クラスと定数
- 定数は大文字で定義
- 呼び出すときは「クラス名::定数」
class Car
REGION = JAPAN
def initialize(name)
@name = name
end
end
Car::REGION
# JAPAN
クラスメソッド
- クラスから直接呼ぶことができるメソッド
- クラスメソッドを定義するときはselfをつける
- インスタンスを生成せずにメソッドが呼べる(initializeメソッドは呼ばれない)
class Car
@@count = 0
def initialize(name)
@name = name
@@count += 1
end
def self.info
puts "#{@@count} instance(s)"
end
end
kitt.info
# 0 instance(s)
クラスの継承
- 親クラス(スーパークラス)の機能を引き継いで、子クラス(サブクラス)を作成できる
- コードの再利用性や拡張性を高める仕組み
class User
def initialize(name)
@name = name
end
def hello
puts "Hello! I am #{@name}"
end
end
# 親クラスUserの機能を引き継げる
class AdminUser < User
def admin_hello
puts "Hello I am Admin"
end
# オーバーライド
def hello
puts "オーバーライド!"
end
end
User.new('Tooyama')
親クラスを確認したい場合
Integer.superclass
# Numeric
モジュール
- クラスのようにメソッドや定数をまとめられるもの
- 関連するメソッドや定数などをまとめてグループ化したいだけの時に、手軽に使えて便利
クラスとの違い
- インスタンスを作ることができない
- 継承ができない
モジュール定義
module モジュール名
# モジュールの定義(メソッドや、定数など)
end
使用例
module Driver
# インスタンスが作れないのでselfをつける
def self.stop
puts "Stop"
end
def self.run
puts "Run"
end
end
Driver.stop # Stop
Driver.run # Run
例外処理
- 予期しないエラーが発生した時、それをキャッチして、ユーザーにメッセージを表示するなど、何らかの処理を行うこと
- 例外が発生した場合それより後の処理は実行されない
puts '--- Please enter an integer. ---'
i = gets.to_i
begin
puts 10 / i
puts 'begin'
rescue => ex
puts 'Error!'
puts ex.message
puts ex.class
ensure
puts 'end'
end
Rubyコーディングルール
メソッドの公開範囲
メソッドにアクセスできる条件をしてできるもの
- public
誰からも見える - protected
- private
自分からしか見えない
class User
def initialize(name)
@name = name
end
# クラス内部のメソッドからは呼びだせる
def say
hello
end
# これより下に書いたコードはprivateメソッドになる
private
def hello
puts "Hello! I am #{@name}"
end
end
tooyama = User.new('Tooyama')
tooyama.hello # NG
tooyama.say # OK
使えそうなメソッド