Open19

Ruby攻略

Takayuki TooyamaTakayuki Tooyama

Ruby基礎

コメント

# コメント

変数(ローカル変数)

変数名 = 式
name = 'Tooyama'

命名規則

  • アルファベットの小文字 (a...z)or アンダースコア(_)で始まる
  • それに続けてアルファベット、数字、アンダースコアで記述
  • マジックナンバーを原則やめる(例 price1 など)
  • _を最初につけるのは意図してつけるとき以外はやめる

定数

  • 大文字で書く
  • 再代入を行わない
TAX = 1.08
TAX_RATE = 1.08
Takayuki TooyamaTakayuki Tooyama

単語理解

オブジェクト指向プログラミング言語

  • コンピュータ・プログラミングの概念の一つ
  • オブジェクト指向の概念や手法を取り入れたもの
  • プログラムを、データとその振る舞いが結びつけられたオブジェクトの集まりとして構成する
     

オブジェクト指向

  • オブジェクト同士が相互に関係し合うことで、システムの振る舞いをとらえる考え方
     

クラス

  • オブジェクトの設計図
     

インスタンス

  • クラス(設計図)から作成した、実態
     

メソッド

  • クラスの中に定義されているもので、複数の処理を一つにまとめて、扱いやすくしたもの
  • クラスに所属する関数のようなもの
Takayuki TooyamaTakayuki Tooyama

Rubyの=== 演算子について

  • javascriptよりもフレキシブ!
場合 説明
左辺が単独のStringやIntegerオブジェクト ==と同じ動作
左辺がClassオブジェクト 右辺がそのクラスのインスタンスであるかどうかを比較する
左辺がRegexpオブジェクト 右辺とマッチするかどうかを取れる

https://mickey24.hatenablog.com/entry/20100910/1284052782
https://techracho.bpsinc.jp/hachi8833/2017_01_19/32941

Takayuki TooyamaTakayuki Tooyama

条件分岐

構文: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 対象のオブジェクトや式
when1
  # 値1に一致する場合の処理
when2
  # 値2に一致する場合の処理
when3
  # 値3に一致する場合の処理
else
  # どの値とも一致しない場合の処理
end
Takayuki TooyamaTakayuki Tooyama

メソッド

def メソッド名 (引数1, 引数2 ...)
  #実行したい処理
end 

メソッド命名規則

  • 小文字の英数で書く(hello)
  • スネークケース(hello_world)
  • マジックナンバーを基本的にはやめる(hello1)
  • 日本語のメソッド名はトラブルを避けるためやめる

戻り値

  • Rubyでは最後に評価された式が戻り値となる
def add(x, y)
  x + y
  # return x + y
end

add(10, 1) # 11
Takayuki TooyamaTakayuki Tooyama

出力方法

puts

  • 改行される
  • 戻り値はnil
puts 'Hello'
# Hello
#  => nil 

print

  • 改行されない
  • 戻り値はnil
puts 'Hello'
# Hello => nil 

p

  • 戻り値は引数のオブジェクト
  • デバック用に使う
p 'Hello'
# => Hello

pp

  • 戻り値は引数のオブジェクト
  • デバック用に使う
  • 適切なインデントと改行で整形される
p 'Hello'
# => Hello
Takayuki TooyamaTakayuki Tooyama

配列操作

下記の通り、配列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

 

Takayuki TooyamaTakayuki Tooyama

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

https://pikawaka.com/ruby/to_i

Takayuki TooyamaTakayuki Tooyama

ハッシュ

{ キー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
Takayuki TooyamaTakayuki Tooyama

繰り返し処理

繰り返し処理を行いたい時に使う

  • 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

 

Takayuki TooyamaTakayuki Tooyama

クラス

# クラス作成
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

 

Takayuki TooyamaTakayuki Tooyama

モジュール

  • クラスのようにメソッドや定数をまとめられるもの
  • 関連するメソッドや定数などをまとめてグループ化したいだけの時に、手軽に使えて便利
     

クラスとの違い

  • インスタンスを作ることができない
  • 継承ができない
     

モジュール定義

module モジュール名
  # モジュールの定義(メソッドや、定数など)
end

 

使用例

module Driver
  # インスタンスが作れないのでselfをつける
  def self.stop
    puts "Stop"
  end

  def self.run
    puts "Run"
  end
end

Driver.stop # Stop
Driver.run # Run
Takayuki TooyamaTakayuki Tooyama

例外処理

  • 予期しないエラーが発生した時、それをキャッチして、ユーザーにメッセージを表示するなど、何らかの処理を行うこと
  • 例外が発生した場合それより後の処理は実行されない
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
Takayuki TooyamaTakayuki Tooyama

メソッドの公開範囲

メソッドにアクセスできる条件をしてできるもの

  • 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