Open32

Ruby Silver 学習まとめ(作成中)

はるはる

前提

  • トータル学習時間:約52時間
  • プログラミング初学者、RailsでCRUDや基礎的な機能の実装は調べながらできる。
  • Railsでもよく使うようなメソッドや概念などはまとめていない部分もある。
  • あくまで試験対策のためあえて簡潔に書いている部分もある。
  • 受験の詳しいレポートについてはnote参照

https://note.com/lemonade37/n/nf8290d8e1c2b

はるはる

Timeクラス・Dateクラス

  • %Y:西暦4桁
  • %y:西暦下2桁

  • %D%x%m/%d/%yと同じ(例 02/03/24…2024年2月3日)
  • %d:日(01〜31)dayのd

  • %F%Y-%m-%dと同じ(例 2024-02-03
    to_sもこれと同じ
Date.today.strftime("%F") #=>2024-02-03
Date.today.to_s           #=>2024-02-03

  • %H:時 hourのh
  • %S:秒 secondのs

時間の足し算・引き算

  • 秒単位で計算をすることが可能。
  • Timeオブジェクトに数値を足す等すると数値を秒として計算し、その秒数経過後のTimeオブジェクトを返す。
    日時同士で足し引きすると、その和や差を秒数で返す。
time1 = Time.gm(2024, 2, 3, 10, 30,  0)
time2 = Time.gm(2024, 2, 4, 10, 30, 0) 

p time2 - time1

Time.gmメソッド

gmメソッドでは引数を(年, 月, 日, 時, 分, 秒)のように解釈してTimeオブジェクトで返す。

p Time.gm(2024, 2, 3, 10, 30,  0) #=>2024-02-03 10:30:00 UTC
はるはる

Rangeクラス

  • ..ドット2つ:1..5は1以上5以下Range.new(1, 5)と同じ。
  • ..ドット3つ:1...5は1以上5未満(5は含まれない)。

1..または1..nil:「上限なし」を表す
nil..nilまたはnil..または..nil:全範囲

はるはる

Hashクラス

ハッシュから取得する系メソッド

  • hash[key]hash.fetch(key):ハッシュから指定したキーに紐づくを取得
  • hash.key(value):ハッシュから指定した値に紐づくキーのうち最初に見つけた1つを取得。引数に渡せる値は1つまで。(ハッシュ内でキーは基本重複しないが値は重複する可能性があるため)
  • hash.keys:ハッシュから全てのキーを配列として取得。引数は渡せない
  • hash.values:ハッシュから全ての値を配列として取得。引数は渡せない
  • hash.values_at(key, key, 〜):ハッシュから指定したキーに紐づく値を配列として取得。引数はいくつでも可
hash = {a: 1, b: 2,c: 3}

p hash.values_at(:a, :b) #=>[1, 2]

p hash.values_at         #=>[]
  • hash.invert:ハッシュのキーと値を逆にした新しいハッシュを生成。引数は渡せない

ハッシュ内に存在するか確認系メソッド

  • hash.key?hash.has_key?hash.include?hash.member?:ハッシュ内にそのキーが存在するかを確認し、存在すればtrueしなければfalseを返す。全て同名の同じ挙動のメソッド。
  • hash.value?hash.has_value?:ハッシュ内にそのが存在するかを確認し、存在すればtrueしなければfalseを返す。
はるはる

イコール系

イコールの数

  • =:代入
  • ==:値が等しい。
  • ===:オブジェクトの型の一致や条件の一致を柔軟に判断するために使われる。case文で使われることが多い。(範囲に含まれるか、正規表現にマッチするか)

eql?とequal?

  • object.eql?(object2):レシーバと引数が等しいとtrueを返す。引数がないとエラーになる。(AugumentError)
  • object.eql?(object2):レシーバと引数の同一性(より厳密)までチェックする。等しいとtrueを返す。引数がないとエラーになる。同じ中身でも別のオブジェクトIDだとfalseになる。
a = "apple"
b = "apple"

p a.equal?(b) #=>false

https://mickey24.hatenablog.com/entry/20100910/1284052782

はるはる

演算子クラス

色々

  • <=>:宇宙演算子。両辺の比較結果を1(>)・0(==)・-1(<)のどれかの数値で返す。
p 3 <=> 2   #=>1
p 5 <=> 5   #=>0
p -1 <=> 0  #=>-1
  • !=:値が等しくない。==の逆。

orの挙動について

m = true
m or n = true
p n  #=> nil

orを使うと、左辺がtrueの時は右辺は実行しない。
しかし、変数nは静的に宣言されている。ただ中身の代入n = trueは実行されていないので、変数nの中身はnilになる。


演算子の優先順位とオーバーライドできるか

優先度 演算子 オーバーライド
高い :: ×
[]
! ~
**
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === != =~ !~
&& ×
|| ×
.. ... ×
? : ×
= += -= ×
not ×
低い and or ×
はるはる

論理積・論理和・&|

  • a && b:aとbが両方trueの場合はbをそのまま返す。aがfalseの場合はbは実行されない。
a = [1, 2, 3]
b = [2, 3, 4]

p a && b #=>[2, 3, 4]
  • a & b:aとbの論理積を返す。
a = [1, 2, 3]
b = [2, 3, 4]

p a & b #=>[2, 3]

Image from Gyazo

  • a || b:aとbが両方trueの場合はaをそのまま返す。aがfalseの場合はbを評価し、bがtrueであればtrueを返す。
a = [1, 2, 3]
b = [2, 3, 4]

p a || b #=>[1, 2, 3]
a = (1 == 2)
b = (1 == 1)

p a || b #=>true
  • a | b:aとbの論理和を返す。
a = [1, 2, 3]
b = [2, 3, 4]

p a | b #=>[1, 2, 3, 4]

Image from Gyazo

はるはる

puts・p・printの違い

  • puts:配列は要素ごとに改行する。ターミナル実行時の戻り値はnil
  • print:別々の行のprintの実行も全て改行なしで出力される。
print 123
print "abc"

#=> 123abc
  • p:配列は要素ごとに改行しない。ターミナル実行時の戻り値はnil
    文字列は""ダブルクォートがついた状態で出力される。
    エスケープ文字(バックスラッシュ付きの正規表現)も変換されずそのまま出力される。
    そのため、デバッグに使用される。

https://zenn.dev/nagan/articles/ae479d26e6d2b0

はるはる

変数・定数

変数・定数とスコープ

  • ローカル変数:アルファベット小文字または_(アンダーバー)で始まる1文字以上のもの。変数名に$などの記号は使えない。
    スコープ:クラス、モジュール、メソッドの壁を越えられない。
  • インスタンス変数:@で始まるもの。
    スコープ:継承で共有されない。インスタンス内で完結。
  • クラス変数:@@で始まるもの。
    スコープ:定義したクラスと、そのクラスを継承したメソッド内で参照・代入可能。クラス変数を持つ同じクラスから生成した別々のインスタンス内で、クラス変数に代入されている値は共有されている。
  • グローバル変数:$で始まるもの。
    スコープ:プログラムのどこからでも参照できる。初期化(定義)していないグローバル変数を参照するとnilが返る。
  • 定数:アルファベット大文字で始まる1文字以上のもの。

定数の再代入

Rubyでは定数の再代入時には、警告メッセージ(warning)は表示されるが、変更やオーバーライドは可能

はるはる

Encordingクラス

  • ソースコードの文字コードを設定するマジックコメントの書き方
    # cording: エンコーディング名
  • マジックコメントとは、ソースファイルの文字コードを指定するためのもの。Ruby2.0以降なら デフォルトでUFT-8 なので指定不要。
  • UFT-8とは、「文字列符号化方式」のひとつ。「コンピュータが使う、文字に割り当てた番号と、実際のコンピュータが扱う数字の対応表」のひとつ。

https://wa3.i-3-i.info/word1812.html

はるはる

埋め込み(文字列リテラル)

a = "Ruby"
p "#{a}を学習する"
#=> "Rubyを学習する"
  • 埋め込みの省略記法
    @インスタンス変数$グローバル変数は下記のような省略した書き方ができる。
@a = "Ruby"
$b = "PHP"
p "#@a と #$b を学習する"
#=> "Ruby と PHP を学習する"
はるはる

破壊的なメソッド

基本的には!が付いていないメソッドは非破壊だけど、!が付いていなくても最初から破壊的なメソッドもある。よく出てくる5つを下記にまとめる。

  • shift:配列の先頭の要素を取り除いてそれを返す。
  • pop:配列の末尾の要素を取り除いてそれを返す。
  • unshiftprepend:引数を与えて使うメソッド。引数で渡すものを配列の先頭に挿入
    引数が2つ以上ある場合は引数の最後から順番に追加される。(引数の並び順通り先頭にくっつくイメージ)
  • pushappend:引数を与えて使うメソッド。引数で渡すものを配列の末尾に挿入
  • concat:破壊的に文字列同士や配列同士を連結させるメソッド。

https://qiita.com/k-penguin-sato/items/ab2267ca99d5aedcc40a

はるはる

Stringクラス 空白文字など取り除く系メソッド

  • strip:文字列の先頭と末尾両方の空白・改行コードなど(\t\r\n\f\v)を取り除く。
    lstrip:文字列の先頭の空白・改行コードなどを取り除く。
    rstrip:文字列の末尾の空白・改行コードなどを取り除く。
  • chomp:文字列の末尾から改行コード(\r\n を取り除く。rstripとの違いは、改行だけを安全に切り取りたい時に使う。(stripだと取り除けるものが多いため)
  • chop:文字列の末尾から文字(文字なんでも)を1つ取り除く。ただし、末尾の文字が改行コード(\r\n)であればその2文字とも取り除く。
  • gsub("a", "b"):文字列中(先頭・末尾でなく間も含む)の、引数aにマッチしたものを全て引数bに置き換える。引数aに空白、引数bに空文字列を指定すると、文字列の間の空白も全て取り除ける。引数aには正規表現も指定できる。
a = "こ ん に   ち は"
p a.gsub(" ", "")
#=> "こんにちは"
  • delete:文字列中(先頭・末尾でなく間も含む)の、引数にマッチしたものを全て取り除く。
a = "こんにちは"
p a.delete("に")
#=> "こんちは"
はるはる

to_◯まとめ

  • to_ss:string)・inspect文字列以外のオブジェクト文字列に変換するメソッド。
    他にも、10進数↔︎◯進数の変換に使用することもできる。(後述)
  • to_ii:integer):文字列を、10進数整数とみなして整数に変換するメソッド。
    整数とみなせないものに対してこのメソッドを使った場合は0を返す。
    他にも、◯進数↔︎10進数の変換に使用することもできる。(後述)
  • to_aa:array):オブジェクト配列に変換する。
    ハッシュ、範囲オブジェクトに使用することが多い。(文字列には使えない
    範囲オブジェクトを使うときは(1..5)のように括弧が必要。
  • to_ff:float):整数浮動小数点数に変換する。
    文字列が渡されると、それを10進数整数とみなして浮動小数点に変換する。
    整数とみなせないものに対してこのメソッドを使った場合は0.0を返す。
  • to_hh:hash):色々なクラスに同名のメソッドがあるが、よく使われるのはキーと値のペアになっている配列(内部の各配列が2つの要素を持っている配列)ハッシュに変換する。
    ハッシュに変換できない形式の配列を渡すとTypeErrorになる。
p [[1,2], [3,4], [5,6], [7,8]].to_h
#=> {1=>2, 3=>4, 5=>6, 7=>8}
  • to_symsym:symbol):文字列に対応するシンボルを返す。
p "hoge".to_sym
#=> :hoge

https://qiita.com/pro_daigo/items/bba9b30660b673d49116

はるはる

◯進数の変換まとめ

to_iを使う方法

  • p '1010'.to_i(2):文字列を2進数とみなして10進数に変換する。例文の出力は=> 10
  • p '20'.to_i(5):文字列を5進数とみなして10進数に変換する。例文の出力は=> 10
  • p 'a'.to_i(16):文字列を16進数とみなして10進数に変換する。例文の出力は=> 10

to_sを使う方法

  • p 10.to_s(2):数値を10進数とみなして2進数に変換した文字列を出力。例文の出力は=> "1010"
  • p 10.to_s(8):数値を10進数とみなして8進数に変換した文字列を出力。例文の出力は=> "12"
  • p 10.to_s(16):数値を10進数とみなして16進数に変換した文字列を出力。例文の出力は=> "a"

oct・hexメソッド

  • oct🐙:文字列を8進数とみなし、10進数整数に変換する。to_i(8)と同じ。
    8進数で解釈できないものが渡された時は0を返す。
  • hex:文字列を16進数とみなし、10進数整数に変換する。to_i(16)と同じ。
    16進数で解釈できないものが渡された時は0を返す。

◯進数の前に付くもの

2進数:0b1011
8進数:0377、0o377
10進数:0d10
16進数:0xffff

https://qiita.com/hmae12/items/4c8949195afa0d7905a1

はるはる

%記法まとめ

  • %%Qダブルクォート1つの文字列になる。
  • %qシングルクォート1つの文字列になる。

  • %W:それぞれの要素を文字列とする配列になる。
    %wとの違いは、大文字%Wの方は#{hoge}などの式の展開がされること。
p %W(a b c)
#=> ["a", "b", "c"]
  • %w%Wと同様だが、埋め込みの式展開がされない。

  • %I:それぞれの要素をシンボルとする配列になる。
    %iとの違いは、大文字%Iの方は#{hoge}などの式の展開がされること。
p %I(a b c)
#=> [:a, :b, :c]
  • %i%Iと同様だが、埋め込みの式展開がされない。
  • %s:引数がひとつの場合は、%iと同じ動きになる。空白で区切ると、下記のような動きになる。
    そのため基本的に%iを使用した方が良さそう。
p %s(abc)
#=> :abc

p %s(a b c)
#=> :"a b c"

  • %xコマンド出力を行う。バッククォートで囲った時と同様。
p `date`
#=> "Wed 14 Feb 2024 11:57:54 AM UTC\n"

p %x(date)
#=> "Wed 14 Feb 2024 11:57:54 AM UTC\n"

https://qiita.com/mogulla3/items/46bb876391be07921743

はるはる

色々な引数まとめ

可変長引数

個数に制限を設けていない引数のこと。その引数は配列として認識される。
メソッドの引数に * をつけると可変長引数として扱われる。

def foo(*a)
  p a
end

foo(1, 2, 3)
#=> [1, 2, 3]

ブロック引数

メソッドの引数に & をつけると引数をProcオブジェクトとして受け取れるようになる。
また、繰り返し文で、あらかじめ定義しておいたProcオブジェクト(ブロック)を引数に渡すなどでも使われる。
(Procについては後述)

# hogeというProcオブジェクトがある時
def method(&hoge)
  hoge.call
end

キーワード引数

メソッドの引数に ** をつけると引数のハッシュを展開してキーワード引数として受け取れるようになる。

def greet(**human)
  p "私は#{human[:name]}です。#{human[:age]}歳です。"
end

greet(name: "花子", age: 25)
#=> "私は花子です。25歳です。"
はるはる

Procクラス

ブロックをオブジェクトとして扱うためのクラス。
そもそもブロックとは、each文などの引数としてよく使われる{|n| p n}などのコードの塊のこと。
Procオブジェクトを作ることで、ブロックを変数に保存したり、メソッドに渡したりすることができるようになる。
名前の無いメソッドのようなもの。(Ruby以外の言語ではこのような処理を無名関数と呼ぶことがある)

proc = Proc.new {|a, b| a + b}
p proc.call(3, 4)
#=> 7

Procに関するメソッド

<クラスメソッド>

  • newProc.newでProcオブジェクトを作れる。

<インスタンスメソッド>

  • call:Procオブジェクトを実行するためのメソッド。
    Procオブジェクトに対して使うことでそのブロックの中身を呼び出せる。
    引数を渡すことで、その引数を呼び出したブロックで実行できる。
  • arity:Procオブジェクトが必要とする引数の数を返すメソッド。
  • curry:引数を部分適応するためのメソッド。複数の引数を取るProcオブジェクトに対して、一部の引数だけを先に渡して、残りの引数を後から渡すことができる。
  • procProc.newとほぼ同じ動きをする。引数にブロックを渡すと、そのブロックをProcオブジェクトに変換する。
  • to_procSymbol#to_procメソッドのこと。オブジェクトをProcオブジェクトに変換するためのメソッド。特に、シンボルや目どっそオブジェクトをブロックとして渡す時に便利。

https://qiita.com/nagata03/items/919b0457409cc755ff0f

https://qiita.com/kasei-san/items/0392097791d3a5998216

はるはる

Mathモジュール

使用するときは、 include Mathと書くか、Mathモジュールの使いたい定数の前にMath::〇〇と書く。Mathメソッドの場合は、Math.〇〇のように.ドットでも可。

  • PIMath::PI):円周率
はるはる

特異メソッド

ある特定のオブジェクトに対してだけ定義されたメソッドのこと。
通常、クラス内に定義されたメソッドはそのクラスの全てのインスタンスで使えるが、
特異メソッドを使うと、ある特定のオブジェクトに対してのみ適応されるメソッドになる。

s = "Hello"
def s.greet
  puts "Hi!"
end

class String
  def greet
    puts "こんにちは"
  end
end

s.greet
#=> Hi!

# ひっかけの他の出力も確認
p s
#=> "Hello"

s = String.new
s.greet
#=> こんにちは
# sというインスタンスを作った後ならs.greetは「こんにちは」になる