💎

Rubyチートシート(一部)

2020/09/27に公開

※この記事は、Qiitaに投稿した記事を一部変更したものです。
https://qiita.com/kunosu/items/37a8222239f3c7f8d59a


徐々に増やしていく予定。

テンプレート

# coding: utf-8

BEGIN {
	puts("#{File.basename(__FILE__)} start\n")
}

END {
	puts("\nend...\n")
}

if $0 != __FILE__
	puts "コマンドプロンプトから直接指定したときだけ実行"
	exit 1
end

# コマンドラインオプションとして"-d"を追加すると$DEBUG=trueになる
puts("デバッグモード") if $DEBUG

# ------------------------------------
# main
# ------------------------------------

# ここに処理を色々書く

実行時の引数を取得

test.rb
# 引数の数が1以外ならNG
if ARGV.size == 1
	folder_path = ARGV[0]
else
	puts "「ruby #{__FILE__} フォルダパス」の形式で実行してください"
	exit 1
end

実行例

> ruby .\test.rb
「ruby .\test.rb フォルダパス」の形式で実行してください

長い式の途中で改行

\(円マーク)をつける

if hogehoge_flg == true && \
	hogehogehogehoge_flg == false
	# なんか処理
end

数値

奇数・偶数を判定

true/falseを返す

num.even?	# 偶数か判定
num.odd?	# 奇数か判定

数値と文字列の変換

数値 -> 文字列

10.to_s # -> "10"
10.123.to_s # -> "10.123"

文字列 -> 整数

"10".to_i # -> 10

# 小数点は無視される
"10.123".to_i # -> 10

文字列 -> 数値

"10.123".to_f # -> 10.123

ループ

指定回数ループ

10.times do |count|
	p count # -> 0 ~ 9まで出力する
end

whileループ

条件式がtrueの間ループする

count = 0
while count < 10
	p count # -> 0 ~ 9まで出力する
	count = count + 1
end

下記のときは最初から条件式がfalseなのでループに入らない(何も出力しない)

count = 10
while count < 10
	p count
	count = count + 1
end

loop-do

内部にbreakを入れないと無限ループになる

count = 0
loop do
	p count # -> 0 ~ 9まで出力する
	count = count + 1

	break if 10 <= count
end

データ構造

Array

# 新規作成
arr = Array.new

# 値を追加
arr.push(1)
arr.push(1)

# 配列が空か判定
if arr.empty?
	# 空のとき実行
end

ループ

arr.each do |value|
	p value
end

# ループする範囲を決める
arr[2...5].each do |value|
	p value
	# => arr[2] ~ arr[4]までの値を出力
end

添字も出力する(0から開始)

arr.each_with_index do |value, index|
	puts "arr[#{index}] = #{value}"
end

Hash

# 新規作成
hash = Hash.new
hash = {:name => "hoge", :num => 1}

# 値を取得
puts hash[:name] # => hoge

文字列

文字列が含まれているか

真偽を返す

str.include?("r")

正規表現に一致するか

str =~ /<(\w+)>/

# 一致しない
str !~ /<(\w+)>/

Regexpを使う場合(変数で比較用文字列を指定するとき)

# \(円マーク)はエスケープする
regexp_str = "<(\\w+)>"

str =~ Regexp.new(regexp_str)

# 一致しない
str !~ Regexp.new(regexp_str)

アルファベットの大文字小文字を区別しないで比較する

# 区別しないで比較したとき一致
"abc".casecmp("abc") # -> 0
"abc".casecmp("ABC") # -> 0

# 一致しない
"abc".casecmp("123") # -> 1

# 部分一致
"abc".casecmp("abcdef") # -> -1
"abc".casecmp("ABcdef") # -> -1
"abc".casecmp("123ABC") # -> 1

一致した部分を置換

# "\"(円マーク)を"/"に変換
folder_path = ARGV[0].gsub("\\", "/")

正規表現も可能

# 第2引数が "" の場合は、一致した部分の削除になる
str.gsub(/<(\w+)>/, "")

文字コード

文字コードの確認と変換

str = "あいう"

# 文字コードの確認
str.encoding
# => #<Encoding:Shift_JIS>

# 変換
str.encode(Encoding::UTF_8)
str.encoding
# => #<Encoding:UTF_8>

ruby test.rb|clipとかで実行結果をクリップボードに送信するときはShift_JISに変換

# 文字列でも指定可能
str.encode("Shift_JIS")

今日の日付

require 'date'

date = Date.today # 日付オブジェクト
p date.strftime("%Y/%m/%d")
# => 2020/05/07

現在時刻

time = Time.now
p time.strftime("%Y%m%d%H%M%S")
# => 20211121134058

環境変数を取得

ENVを使う

test.bat
set ACCESS_TOKEN=123456789
ruby test.rb
test.rb
access_token = ENV['ACCESS_TOKEN']
# => 123456789

環境変数が未設定の場合は nil を返す

test.rb
access_token = ENV['ACCESS_TOKEN_NIL']
# => nil

# 未設定かチェックする
str = 'ACCESS_TOKEN_NIL'
if !ENV.has_key?(str)
	raise ArgumentError, "環境変数 #{str} に値が設定されていません"
end

入力を受け取る

文字列で受け取るため、数値として扱いたい場合はto_iで変換する必要がある

test.rb
print "実行しますか?(y/n): "
input_str = gets.chomp	# 改行も受け取るのでchompで削除する

if input_str != "y"
	puts "#{input_str}が入力されたので終了します"
	exit 0
end
> ruby test.rb
実行しますか?(y/n): 	# ここで実行が止まるので何か入力+Enter

未入力のままEnterを押しても進むので、それを防ぎたいときはループを使う

input_str = ""
while input_str == ""
	print "実行しますか?(y/n): "
	input_str = gets.chomp
end

例外

例外の一覧はこちらの「例外クラス」参照
Ruby リファレンスマニュアル: https://docs.ruby-lang.org/ja/latest/library/_builtin.html

例外をキャッチする

begin
	# 例外が発生
rescue => error
	# ここで例外処理を行う

	# エラーメッセージに追加できる
	raise error, "#{error.message}:XXXです"
end

例外を発生させる

raise ArgumentError	# 引数エラー
raise ArgumentError, "xxxが存在しません" # メッセージもつけれる

ブロック

メソッドにブロックを渡す(ブロック引数)

ファイルを開くまでの処理を共通化したいとき

# 指定フォルダ配下にあるファイルを1つづつ開いて、blockに処理させる
def read_file(dir_path, file_name, &block)
	dir_path.each_child do |path|
		# 正規表現に合わないファイル名は無視
		next if path.to_s !~ Regexp.new(file_name)

		puts "Reading #{path.basename}"

		path.open(mode = "r", :external_encoding => "UTF-8") do |file|
			# ブロックにfileを渡す
			block.call(file)
		end
	end
end

# test_*.txtのファイルのみ読み込んで出力する
# ※通常のメソッドのように()で引数を囲わない
read_file dir_path, ".+/test_\\w+\\.txt$" do |file|
	# ここに書いたことが、&blockとしてread_fileに渡される

	line.chomp!	# 改行削除
	next if (line == "")	# 空行を無視

	puts line
end

Class

オブジェクトのクラスを調べる

1.class # -> Integer
"aaa".class # -> String

arr = Array.new
arr.class # -> Array

指定クラスのインスタンス変数か判定

test_pathがPathnameのインスタンス変数か判定するとき

if test_path.is_a?(Pathname)
	p test_path.basename
end

既存クラスの拡張

インスタンスメソッドを追加する

例:Pathnameクラスの拡張

require 'pathname'

class Pathname
	# ファイル名に使用不可の文字があるならtrue
	def is_filename_unavailable_str?
		file_name = self.basename.to_s
		return (file_name =~ /[:\*\?\"><\|]/)
	end
end

# 通常のインスタンスメソッドのように使える
file_path = Pathname.new("C/:...")
if file_path.is_filename_unavailable_str?
	raise ArgumentError, "#{file_path.basename}はファイル名として使用不可です"
end

クラスメソッドを追加する

ARGVの拡張

require 'pathname'

# 指定した実行時引数をPathnameのインスタンス変数に変換
def ARGV.to_pathname(i)
	return Pathname.new(ARGV[i])
end

# 通常のクラスメソッドのように使える
text_path = ARGV.to_pathname(0)

アクセス権を制御する

C++と同じ名前でpublic, protected, privateの3つがある

class Hoge
	# デフォルトでは全部public
	def public_method
		puts "called public_method"
	end

	# 以降はprotectedになる
	protected
	def protected_method
		puts "called protected_method"
	end

	# 以降はprivateになる
	private
	def private_method
		puts "called private_method"
	end

	# 下記でも指定できる
	# private :private_method
end

hoge = Hoge.new
hoge.public_method #=> called public_method
hoge.protected_method #=> エラー
hoge.private_method #=> エラー
名前 公開範囲
public 全部
protected クラス内、同一パッケージ、サブクラス
private クラス内のみ

Discussion