💎
Rubyチートシート(一部)
※この記事は、Qiitaに投稿した記事を一部変更したものです。
徐々に増やしていく予定。
- 環境
- Windows10
- Ruby 3.1.1
- 長くなってきたので記事を分割
テンプレート
# 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
を使う
- 参考
- object ENV(Ruby 3.0.0 リファレンスマニュアル) < https://docs.ruby-lang.org/ja/latest/class/ENV.html >
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