Chiroru's Diary

日々の学びをちょこちょこメモしていきます

Machida.rb #05に参加しました!

毎月第1金曜日に開催されているMachida.rbに、前回に引き続き2回目の参加をしました!
【目次】

今回はRubyで簡単な問題を解いてレビューし合う勉強会でした💪その中の問題を抜粋して書きます。

Rubyの問題を解いてみた

FizzBuzz

有名なFizzBuzz問題の省略版です。1~20の数字を出力するうち、3の倍数ではFizz・5の倍数ではBuzz・3と5の倍数ではFizzBuzzと出力させます。

最初のコードはこちら。

(1..20).each {|num|
  if num % 15 == 0
    puts "fizzbuzz"
  elsif num % 3 == 0
    puts "fizz"
  elsif num % 5 == 0
    puts "buzz"
  else
    puts num
  end
}

このコードで注目したのは「putsを毎回書いている」という点です。

これは以下のようにif文を()で括りそれに対してputsすることで、何度も書いていた部分が改善できるようになりました。

(1..20).each {|num|
  puts (if num % 15 == 0
   "fizzbuzz"
  elsif num % 3 == 0
    "fizz"
  elsif num % 5 == 0
    "buzz"
  else
    num
  end)
}

しかしさらに、「putsの位置」について改善できます。

上記ではループ処理の中にputsを置いているのですが、それより以下の書き方では「処理の結果(戻り値)を出力している」ことになるのでこちらの方がより良いとのことです。

puts (1..20).map {|num|
  if num % 15 == 0
   "fizzbuzz"
  elsif num % 3 == 0
    "fizz"
  elsif num % 5 == 0
    "buzz"
  else
    num
  end
}

パタトクカシーー

出題は言語処理100本ノックより「パタトクカシーー」問題です。
文字列の奇数番を取り出して「パトカー」と連結した文字列を取得します。

はじめに解いたコードはこちらなのですが、nilが出力されてしまってうまく出力ができませんでした😓

str = "パタトクカシーー"
p str.chars.each_slice(2) {print _1[0]}
# => パトカーnil

この原因はeach_slice(n) {|list| ... } -> nilのように、each_sliceの戻り値がnilを返すためでした。※
文頭にpを書いてしまっているため、この戻り値nilを拾って出力してしまっていました。

参考:リファレンスマニュアルEnumerable#each_slice

なので、こちらだったらいけますね。
putsは内部でto_sしてるいるのでnilは出力されません。

str = "パタトクカシーー"
puts str.chars.each_slice(2) {print _1[0]}
# => パトカー

しかしこれもまた、ブロック内部でprintをしてしまっているので、FizzBuzzの所に書いたように「戻り値を出力する」という方針でこちらの方が良いです↓

str = "パタトクカシーー"
puts str.chars.each_slice(2).map { _1[0] }.join
# => パトカー

※ちなみにeach_slice(n) -> Enumeratorのように、blockを持たなければeach_sliceの戻り値はEnumeratorになります。

感想

その場で解くにはちょうどいい問題の難易度で、人のコードと比較したり、すぐにレビューを受けられる&質問できるとても充実した勉強会でした! p・print・putsの挙動や適切な配置、Enumerator関連のメソッド(each_slice)がブロックを持つ時の戻り値がnilであることなど、学びもたくさんありました! また勉強会後の懇親会では、rubykaigiの直後だったこともありkaigi内の発表のことやruby3.0について技術的な話が聞けてとても楽しかったです!