プログラミング備忘録

プログラミングの学習状況をメモしています

35日目

今日の学習

Ruby

CODEPREPで基礎の練習

昨日、課題に取り組んでいるときに、あまりにも自分に基礎が身に付いていないと感じたので、CODEPREPで基礎の学習。

codeprep.jp

演習は、期待する戻り値はどうすれば返せるか?という良い練習になったと思う。

正直、一つの問題を解くのにかなり時間がかかっており、やっと出来上がったコードもかなり冗長なものが多く、今後が心配になる。

知らなかったもの等をメモしておく。

メソッド
  • shift
    配列の先頭から要素を取り出す
    また、引数で数値を渡すと、その分だけ要素を取り除き、取り除いた要素を配列で返す
  • unshift
    配列の先頭に要素を追加する
  • pop
    配列の末尾から要素を取り出す
  • array1 & array2
    配列同士を&で繋ぐと、配列同士の共通要素を求めることができる
  • <=>演算子 array1 <=> array2
    返り値が0の場合:配列が等しい
    1の場合:異なる箇所があり、左項の配列の要素が大きい -1の場合:異なる箇所があり、右項の配列の要素が大きい
  • zip
    複数の配列から多重配列を作る
  • invert
    ハッシュのキーと値を入れ替えたハッシュを作成する
  • inject
    Ruby の inject(reduce) メソッドを使いこなす - Hack Your Design!

特異メソッド

特定のオブジェクトにだけ紐づくメソッドのことを特異メソッドと呼ぶ。

オブジェクト名.メソッド名の形で定義し、該当するオブジェクト以外では呼び出すことができないメソッドになる。

クラスメソッドは、この特異メソッドの一種。

モジュール

たまに名前を見る機会があったモジュールというものをRuby本で学習。

ざっくり言うと、「特定のクラスだけではなく、さまざまなクラスで呼び出すことができるメソッド」という解釈になるのだろうか。

モジュールの定義

モジュールは、

module Greeter
  def hello
    'hello'
  end
end

このように、module モジュール名として、その下にメソッドや定数などの情報を書いていく。見た目としては、classとほとんど一緒に見える。

モジュールの大きな特徴は、

  • モジュールからインスタンスを作成できない

  • ほかのモジュールやクラスを継承できない

の二点で、クラスの大きな特徴であるインスタンス生成や継承といった要素が使えない。

では、どういうときにモジュールを活用するのかというと、やはり異なるクラスにおいて同様のメソッドを利用したい場合に活用するようだ。

また、helloメソッドはpublicメソッドになるので、メソッドの外部で呼び出されたくない場合はモジュール内でprivateメソッドとするのが良い。

module Greeter
  # privateキーワードをつける
  private

  def hello
    'hello'
  end
end
ミックスイン

重複するコードをまとめるために、モジュールに使いまわしたいメソッドを定義して、クラス内でモジュールをincludeすることによってモジュールで定義したメソッドがインスタンスメソッドとして使用できるようになる。

# 先ほどのGreeterモジュールを他のクラスで使うには...

class Animal
  include Greeter
...
...
class Product
  include Greeter
...
...
end

AnimalクラスとProductクラスで、先ほどのhelloメソッドが使用できるようになった。

このように、モジュールをクラスにincludeすることをミックスインと言う。

モジュールが複数あるのであれば、複数回ミックスインすることも可能。

extend

モジュールをクラスにミックスインする別の方法に、extendがある。

extend モジュール名とすることで、モジュール内のメソッドを特異メソッドとしてミックスインすることが可能。

...と書いたものの、正直特異メソッドに関するメソッドも、extendを利用するメリットもいまいち分かっていない。

クラス構文の直下ではクラスメソッドしか呼び出せないため、その際にミックスインする場合はextendを使ってクラスメソッド(特異メソッド)としてモジュールを追加するということらしい。

includeで追加するとインスタンスメソッドに、

extendで追加するとクラスメソッドになる。

と考えると、確かに違いはある。クラスに使いたいメソッドの場合は、extendとすれば良さそうだ。

もっとインスタンスメソッド、クラスメソッドの違いへの理解を深める必要性をひしひしと感じた。

https://pikawaka.com/ruby/include

学習メモ