📑

Grow.rbのmy_map問題を解いてみる

2024/12/14に公開

Grow.rbとは:

Ruby力を高めたいRubyistたちが、コードを書いたりちょっとマニアックな内容を学んだりするコミュニティです。

オリジナルのmapメソッドを作ってみようというテーマです。
テストコードはこちら。

https://github.com/grow-rb/enumerable-exercises/blob/d08568e5319c9d24a74c9cb635ed1115ad43adc3/map/map_test.rb#L1-L16

自分で考えた回答たちはこちら。

module Enumerable
  def my_map(&block)
    result = []
    each do |arg|
      result.push(block.call(arg)) if block_given?
    end
    result
  end
end

上記のメソッドとは違い、Procオブジェクトをcallするのではなくブロックをyieldするようにしたものがこちら。

module Enumerable
  def my_map
    result = []
    each do |arg|
      result.push(yield(arg)) if block_given?
    end
    result
  end
end

オリジナルのmapメソッドを作ろうという話なのに、本家のmapメソッドを使うという暴挙がこちら。やっぱりこういう変数を使わないRuby的な値の返し方は好き。

module Enumerable
  def my_map(&block)
    map do |arg|
      block.call(arg) if block_given?
    end
  end
end

上記コードたちをもとに、ChatGPT(4o)にリファクタを提案してもらったのがこちら。

module Enumerable
  def my_map
    return to_enum(:my_map) unless block_given?

    result = []
    each do |arg|
      result.push(yield(arg))
    end
    result
  end
end

私が作った回答ではblock_given?のfalseの場合が考慮されていなかったため、それが考慮された形となっている。to_enumでEnumeratorオブジェクトを返している。

また、引数にProcオブジェクトを受け取るのではなく、受け取ったブロックをそのままyieldしている。

Discussion