Ruby学習 基本
Rubyについて学習した内容をまとめていきます
ドットインストールを使って学習
# いろいろな出力方法
print "hello woeld"
puts "hello world" # 改行あり
p "hello world" # デバッグ用
# オブジェクト
human = {
name: "taro",
age: 20,
gender: "男性"
}
p human
# {:name=>"taro", :age=>20, :gender=>"男性"}
# 1行コメント
=begin
複数行コメント
複数行コメント
=end
実行 ruby {ファイル名}
変数・定数
=begin
変数名は小文字で始める
変数名はスネークケースで書く
変数名は数字で始めることはできない
変数名はアルファベットの大文字小文字、数字、_が使える
変数名は同じ名前を使えない
変数名は予約語を使えない
変数名は名前をつけることでコードの意味がわかりやすくなる
=end
msg = "hello world"
puts msg
# 上書きも出来る
msg = "hello world again"
puts msg
=begin
定数名は大文字で始める
=end
VERSION = 1.1
puts VERSION
VERSION = 1.2
puts VERSIONv
warning
hello.rb:24: warning: already initialized constant VERSION
hello.rb:21: warning: previous definition of VERSION was here
数値
# 数値
# p 4.8.class
# p 4.8.methods
p 4.8.floor # 小数点以下切り捨て
p 4.8.ceil # 小数点以下切り上げ
p 4.8.round # 四捨五入
式展開
name = "Alice"
p "Hello, #{name}!"
p 'Hello, #{name}!' # シングルクォートだと式展開されない
真偽値はシンプルで、下記のようになっている
偽: false nil
真: それ以外
rubyの短絡評価
左辺でfalseが出た場合、右辺はそもそも処理しない。
この特性を利用して
user
user || user.email_veryfied # userがnilやfalseの場合、右辺処理を行わない
というようにコードを書いたりする
条件分岐
boy = 'men'
girl = 'women'
def gender(human)
if human == "men"
puts "男です"
elsif human == "women"
puts "女です"
else
puts "不明です"
end
end
gender(boy) # 男です
gender(girl) # 女です
後置if
# 後置if
human = {
age: 20,
name: "Alice"
}
puts "Aliceです" if human[:name] == "Alice"
unless
# unless
hoge = false
unless hoge
puts "falseです"
else
puts "trueです"
end
case
animal = "cat"
case animal
when "dog"
puts "犬です"
when "cat"
puts "猫です"
when "bird"
puts "鳥です"
else
puts "それ以外です"
end
三項演算子
score = 100
# 条件式 ? 真の時の処理 : 偽の時の処理
puts score > 80 ? "great" : "bad"
メソッド定義
def メソッド名
# 処理
end
?と!で終わるメソッド
Rubyのメソッドには、nil?のように?や!が付くメソッドがあります。
基本的に?が付くメソッドは、真偽値を判定しているメソッドになります。
!が付くメソッドは破壊的なものになる
破壊的とは、オブジェクトの中身を変更してしまうものなどの事になる
(基本的には、破壊的メソッドの仕様は控えた方がよさそう!)
配列
# 色々な書き方がある
testArr = [1, 2, 3, 4, 5]
p testArr[0] # 1
p testArr[1] # 2
p testArr[-1] # 5
p testArr[-10] # nil
p testArr[0..2] # [1, 2, 3]
# 要素の変更
testArr[7] = 10
p testArr # [1, 2, 3, 4, 5, nil, nil, 10] # 存在しない要素に代入すると間の要素はnilで埋められる
# testArr[-10] = 10
# p testArr # 負の数では、存在しない要素に代入するとエラーになる
# <<を使うと配列の最後に要素を追加できる
testArr << 6
p testArr
# pushを使っても配列の最後に要素を追加できる
testArr.push(7)
p testArr
# 配列に連続して追加できる
testArr << 6 << 7
配列の分割
splitメソッドを使うと、文字列を自然に変換した配列を得ることができます。
デフォルトでは、空白で分割する
# 文字列を3つの要素を持つ配列に分割する
"foo bar baz".split
=> ["foo", "bar", "baz"]
# 好きな文字で分割するように、指定することも出来る
>> "fooxbarxbaz".split('x')
=> ["foo", "bar", "baz"]
範囲(range)は、配列と密接に関係しています。to_aメソッドを使って配列に変換すると理解しやすいと思います。
# 丸カッコを使い、範囲オブジェクトに対してto_aを呼びましょう
(0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 範囲は、配列の要素を取り出すのに便利です。
# %wを使って、文字列の配列に変換することも出来る
a = %w[foo bar baz quux]
=> ["foo", "bar", "baz", "quux"]
# 範囲で取得できる
a[0..2]
=> ["foo", "bar", "baz"]
ハッシュとシンボル
ハッシュは、他で言語でいうオブジェクトとか、連想配列
シンボルの特徴
- 文字列(string)と似てる
- ふるまいが似ているが、若干異なるので適材適所で使用する
- そもそも、文字列っぽいけど内部では整数として扱われている
- その為、より高速に比較ができる
- 同じ名前のシンボルならば、同じオブジェクトになる
- idなどが同じになる
- 破壊的メソッドが使えない(immutable:変更不可)
ハッシュなどのキーにはシンボルをよく使う
money = {
:taro => 100,
:hanako => 200
}
キーにシンボルを使う場合、省略した書き方ができる(JavaScriptのオブジェクトに似た書き方なので、良さそう)
money = {
taro: 100,
hanako: 200
}
さらにメソッドの最後がハッシュの場合 {}も省略できるので、初見で意味不明な形にもなります
def print_hello(greet, options)
puts options
puts greet
end
# 省略の流れ
print_hello('hello', {taro: 100, hanako: 200})
print_hello 'hello', {taro: 100, hanako: 200} # メソッドの()は省略可能
print_hello 'hello', taro: 100, hanako: 200 # メソッドの引数の最後が、ハッシュなので{}を省略
Rubyのオブジェクトの注意点
インスタンス変数がおかしい場合でも、errorを吐かず、nilが入ってしまうので注意
(initializeに入っているものは、値が入れられない場合nilを返すのだと思う)
インスタンス変数は外部から参照することは出来ない
ゲッター
インスタンス変数の値を取得したい場合、それ用のメソッドを作る必要がある
class Human
def initialize(name, age)
@name = name
@age = age
end
def description
puts "#{@name}と申します。年齢は#{@age}です。"
end
def name
@name
end
end
セッター
インスタンス変数の値を変更したい場合、=で終わるメソッドを定義する
class Human
def initialize(name, age)
@name = name
@age = age
end
def description
puts "#{@name}と申します。年齢は#{@age}です。"
end
def name
@name
end
def name=(new_name)
@name=new_name
end
end
ただ、毎回ゲッター、セッターを書くのは冗長なので省略する書き方が存在する
attr_accessorと書くことで、ゲッターとセッターを書いたとみなされる
下記のbeforeとafterは同じように使えるコードになる
before
class Human
def initialize(name, age)
@name = name
@age = age
end
def description
puts "#{@name}と申します。年齢は#{@age}です。"
end
def name
@name
end
def name=(new_name)
@name=new_name
end
end
after
class Human
attr_accessor :name
def initialize(name, age)
@name = name
@age = age
end
def description
puts "#{@name}と申します。年齢は#{@age}です。"
end
end
さらに、読み取りだけしたい場合
attr_reader
書き込みだけしたい場合は
attr_writer
という書き方も出来る
クラスメソッド
2種類の書き方
基本的にはこちらを使う
def self.メソッド名
puts "このメソッドを実行"
end
複数のメソッドを定義する場合は、こちらの方が効率が良い
class << self
def メソッド名
puts "このメソッドを実行"
end
def メソッド名2
puts "このメソッド2を実行"
end
end
クラス内の定数と変数
スコープが異なり
定数はインスタンスメソッドや、クラスメソッド内からも呼び出せる
class Human
attr_accessor :name
RURU = "どこからでも呼び出せる"
ruru = "呼び出す場所は同スコープ内のみ"
def initialize(name, age)
@name = name
@age = age
puts RURU # どこからでも呼び出せる
puts ruru # エラー
end
def description
puts "#{@name}と申します。年齢は#{@age}です。"
end
end
# 外部からも参照できる
puts Human::RURU # どこからでも呼び出せる
privateメソッドについて
privateメソッドはクラス内部でのみ使うことが出来る
※ privateと書いた以降の記述はすべてprivateになる
class Human
attr_accessor :name
def initialize(name, age)
@name = name
@age = age
end
private # ここから下の記述はprivateになる
def walk
puts '毎日歩いています'
end
end
継承
書き方はシンプルで以下のように書くだけ
継承したクラスの事は、スーパークラスと呼ぶ(親クラス)、子クラスはサブクラスと呼ばれる
親クラスと同じメソッド名の場合、superと記述することで、親の挙動をそのまま使える
子クラス側で、同名メソッドを上書きすることをオーバーライドと呼ぶ
class クラス名(大文字から始まる) < 継承するクラス名
ブロック
下記処理の説明
範囲オブジェクトである(1..5)に対してeachメソッドを呼び出しています
| i |で、変数が縦棒「|」に囲まれているのが、ブロック変数のRubyの構文です。
(1..5).each {
| i | puts 2 * i
}
2
4
6
8
10
=> 1..5
波カッコ の替わりに doとend で囲んで示すこともできる
(1..5).each do |i|
puts 2 * i
end
symbol-to-procという記法もあり、&:メソッド名で省略して書くことも出来る
%w[A B C].map { |char| char.downcase }
=> ["a", "b", "c"]
# これをsymbol-to-procを使って書くと
%w[A B C].map(char:downcase) # と書くことも出来る
=> ["a", "b", "c"]
ここまでに学習した書き方を使うとこのようになる。
def yellar(stringArray)
stringArray.map(&:upcase).join
end
array = ['a', 'b', 'c']
yellar(array)
=> ABC
新しく覚えたこと
配列操作
.uniq
配列から重複する値を除いたものを返す
array.uniq
.map
配列の各要素に対して処理を行った結果を配列で返してくれるメソッドです。
# 基本構文
配列.map { |item| 実行する処理 }
# 実行する処理が複数行に渡る場合
配列.map do |item|
実行する処理
end