ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

Rubyの基本構文メモ

Rubyの基本的な構文についてざっとメモしておきたいと思います。


Rubyとは

まつもとゆきひろ氏により開発されたオブジェクト指向スクリプト言語
「楽しくプログラムを書ける」ことを目指して作られたとか。

●公式サイト

オブジェクト指向スクリプト言語 Ruby

ドットインストールで学習を進めてみる

Ruby入門(全26回)』が学習におすすめです。

Ruby 2.3.1 での解説(2019年5月時点)
・ローカル開発環境でレッスンが進む
 Vagrantで仮想環境にRubyをインストールした状態
 参考になるのは同じドットインストールのこちらのレッスン
 https://dotinstall.com/lessons/basic_localdev_win_v2

●便利なターミナルコマンド

irb ‥ 対話型になるのでRubyのコードをお手軽に試せる
ri ‥ ヘルプ情報を検索、一覧できる
q ‥ 上記モードは「q」キーで抜けられる


コメントアウト

[一行コメントアウト]
#

[複数行のコメントアウト]
=begin
 ~~
=end


●文字列の表示

print "hello world" # 改行なし
puts "hello world" # 改行あり
p "hello world" # デバッグ


●変数

英小文字かアンダーバーで始めるルール。

name = "taro"


●定数

英大文字から始めるルール。
慣習的に全て大文字にする場合が多い。

NAME = "taro"


●オブジェクト

便利な命令(メソッド)を色々持っているデータ型。

オブジェクトの種類をクラスと呼ぶ。
String Class とか Float Class とか。

設計図であるクラスを new して実体を持ったものをインスタンスと呼ぶ。

●数値

どんなクラスがあるか / メソッドがあるか調べる場合はこちら。

p オブジェクト名.class
p オブジェクト名.methods


●文字列

"~" と '~' どちらでも良いが違いがある。

"~" は特殊文字が扱えて、式展開ができる。

特殊文字 ‥ \n \t など
・式展開  ‥ #{~}

式展開は、波カッコ内で計算式を書いたり変数を使える。

name = "taro"
puts "hello #{name}" 


●文字列の連結

puts = "hello " + "world"
puts = "hello" * 10


! メソッド

upcase ‥ 文字列を大文字にして返す
upcase! ‥ 文字列を大文字にして返しつつ元の文字列も大文字にする
downcase ‥ 文字列を小文字にして返す
reverse ‥ 文字列を逆順に並び変えて返す

「!」は大元のオブジェクトを書き換えるので「破壊的なメソッド」と呼ばれる

name = "taro"
puts name.upcase

name = "taro"
puts name.upcase!


? メソッド

真偽値を返す true false

p name.empty? ‥ 変数nameが空かどうかを返す

p name.include?("m") ‥ 特定の文字が含まれているかを返す


●配列

msgs = ["あ", "い", "う"]
p msgs[0] # []内を添字と言う
p msgs[-1] # 末尾
p msgs[-2] # 末尾から2番目
p msgs[0..2] # 0~2番目のもの
p msgs[0...2] # 0~2番目の直前のもの
p msgs[5] # 範囲外の指定をするとnilが返る

msgs.push("") ‥ 要素を追加する
msgs << "" ‥ 追加の簡略した書き方
msgs.size ‥ 含まれている要素数を返す
msgs.sort ‥ 要素を昇順でソート


●ハッシュ

key キー と value 値 をペアで管理する。

ages = {"taro" => 24, "hanako" => 20}


Rubyでは「:(コロン)」で始まるシンボルオブジェクトがよく使われる。
文字列を扱うよりも高速。

ages = {:taro => 24, :hanako => 20}
ages = {taro: 24, hanako: 20} # 簡略化した書き方
p ages[:taro] # 24が返ってくる
ages[:taro] = 30 # 30に書き変わる

p ages # {:taro => 24, :hanako => 20}がまるごと返ってくる
p ages.size ‥ 要素の数
p ages.keys ‥ keyの一覧
p ages.values ‥ valueの一覧
p ages.has_key?(:jiro) ‥ 指定したキーを含むか真偽値で返す


●型の変換

データ型を変換する場合。

var.to_i ‥ 整数型に変換
var.to_f ‥ 不動小数点型に変換
var.to_s ‥ 文字列型に変換
vars.to_a ‥ ハッシュを配列に変換
vars.to_h ‥ 配列をハッシュに変換


● 

%は文字列の中で「”」や「'」といった区切り文字を使いたい場合に便利。

puts %Q(he\"llo)
puts %(he”llo) # 大文字のQは省略できる
puts %q(he’llo)

p ["あ", "い", "う"] # 区切り文字が面倒な場合、次のように省略できる
p %W(あ, い, う)

文字列に値を埋め込む方法 ※C言語のような
%s ‥ 文字列の場合
%d ‥ 整数の場合
%f ‥ 不動小数点の場合

p "name: %s" % "taro"
p "name: %10s" % "taro" # 10桁分で返す
p "name: %-10s" % "taro" # 10桁分でかつ左詰めで返す

p "id: %d, kg: %f" % [2, 50.67]
 ⇒ 結果 "id: 2, kg: 50.67"

p "id: %05d, kg: %5.1f" % [2, 50.67]
 ⇒ 結果  "id: 00002, kg:    50.6


●ユーザーからの入力を受け付ける

msg = gets # 受け取るのは文字列になる
msg = gets.chomp # 改行コードを取り除く


●比較演算子

> ‥ ~より大きい
< ‥ ~より小さい
=> ‥ ~以上
<= ‥ ~以下
== ‥ 等しい
!= ‥ 等しくない


●論理演算子

&& ‥ AND
|| ‥ OR
! ‥ NOT


●条件分岐

if を使う場合

if 条件 then # thenは省略できる
 ~処理~
elseif
 ~処理~
else
 ~処理~
end


caseを使う場合。

case
 ~
when "" then
 ~処理~
when "" then
 ~処理~
else
 ~処理~
end


i = i + 1 ‥こちらを簡略化するにはi += 1


●繰り返し

whileで10回繰り返す。

i = 0
while i < 10 do
 ~処理~
end


timesで10回繰り返す。

10.times do
 ~処理~
end


i でカウントしてくれる。

10.times do |i|
 ~処理~
end

# 簡単な処理の場合に1行で省略できる書き方
10.times { |i| ~ }

# 3から8を変数iに格納している doは省略できる
for i in 3..8 do
 ~処理~
end


forで配列・ハッシュ。

# 配列
for i in ["あ", "い"] do # 配列を変数iに格納している
 ~処理~
end

# ハッシュ
for i in {taro:24, hanako:20} do # ハッシュを変数iに格納している
 ~処理~
end

#
forの内部はeachが使われている
(3..8).each do |i|
 ~処理~
end

["あ", "い"].each do |msgs|
 ~処理~
end

{taro:24, hanako:20}.each do |name, age|
 ~処理~
end


loop
永久にループする。

i = 0loop do
 ~処理~
end

 


ループ中、ターミナルで Ctrl + C でループを抜けられる。
またはこちらを使う(ifと一緒に使ったりする)。

break ‥ ループを抜ける
next ‥ ループを1つスキップする


●メソッド

定義する場合。

def メソッド名(引数)
 ~処理~
end

# デフォルト値を指定する場合(引数省略時に使われる)
def hello(name = "taro")
puts "hello #{name}"
end

# 返り値がある場合、基本的に最後に評価した値が返る
# 明示的にするならreturnを書く


使用する場合。

メソッド名(引数)
メソッド名 引数 ‥のように()を省略できる場面がある


●クラス

クラス名は最初の文字を大文字にする。

定義する場合。

class クラス名
 def メソッド名
  ~処理~
 end
end


使用する場合。

インスタンスの生成変数名 = クラス名.new
メソッドを呼び出すクラス名.メソッド名


初期化する場合。
※インタンス生成時に格納するインスタンス変数は@を付ける

class クラス名
 def initialize(name)
  @name = name
 end
 def メソッド名
  ~処理~
 end
end


●アクセサ

外部からアクセスしたい場合はクラス内に下記のように定義する。

attr_accessor :name

# インスタンス変数の名前をシンボルで渡す
# すると下記の2つのメソッドを自動的に作ってくれる
name=(value) ‥ セットするためのメソッド(セッター)
name ‥ ゲットするためのメソッド(ゲッター)


ゲッターだけ定義して欲しい場合は下記のように書けばOK。

attr_reader :name


●self

自身のインスタンスを指定できる。
こちらのように書けばインスタンス変数nameのゲッターを自ら呼び出せる。

self.name # selfは省略できる


●クラスメソッド

インスタンスを生成しないと使えないインスタンスメソッドとは違って、newしなくてもいきなり使えるのがクラスメソッド。

定義する場合、クラス内に下記のように記述すればOK。

def メソッド名.info
 ~処理~
end


●クラス変数

全てのインスタンスで共有される変数のこと。

@@変数名 = 初期値


●クラス内の定数

全て大文字で定義する。
外からアクセスする場合‥

変数名 = クラス名.new
変数名::クラス内の定数名


●クラスの継承

class クラス名 < 継承元のクラス名
 def メソッド名
  ~処理~
 end
end


継承元のクラスを「親クラス」や「Super Class」と呼ぶ。
継承先のクラスを「子クラス」や「Sub Class」と呼ぶ。
継承時に親クラスのメソッドと同じメソッドを定義して内容を変えることもできる(オーバーライド)。

●メソッドのアクセス権

public ‥ どこからでも呼び出せる
protected ‥ 特殊ケース
private ‥ レシーバーを指定できないメソッド(インスタンスから呼べない)


他の言語と違ってオーバーライドが可能だったり子クラスから呼べる。

private
 def メソッド名
  ~処理~
 end
end


●モジュール

メソッドや変数を定義できるがインスタンスを作ったり継承ができない。
自分だけの名前空間を作ることで名前の衝突を防げる。

module モジュール名 # 先頭を大文字にする
 def メソッド名
  ~処理~
 end
end


●ミックスイン

複数のクラスで同じような機能が必要な場合にモジュールを作って流用する。
モジュール内のメソッド名の代わりにinfoを付ける。

定義する場合。

module モジュール名A
 def info
  ~処理~
 end
end


使用する場合。

class クラス名B
 include モジュール名A
end

class クラス名C
 include モジュール名A
end

クラス名B.new.info
クラス名C.new.info


●例外処理

エラーが発生した時に特定の処理を行うようにする場合の文法。

begin
 ~例外が発生しそうな処理~
rescue => ex p ex.message
p ex.class

puts "エラー発生!"

ensure
 ~例外が発生してもしなくても実行する処理~
end


他にありがたかった記事をペタリと。

以上、ざっくりメモでした。