【Ruby】Ruby BitsからRubyらしいコードを学ぶ - Expressions編 -

PythonからRubyに転向しようとしている私ですが、Pythonを始めた時にも"Pythonic"な書き方に悩まされました。

というわけで、CodeSchoolさんのRubyBitsからRubyらしいコードの書き方を学んでいきます。

1. if式でネガティブなコンディションをtrueとする場合はunlessを使う

flag = false

if !flag
    puts "condition true"
else
    puts "condition false"
end

これくらいなら読みにくくありませんが、condition部分は常にtrueになっていてほしいものです。
なので、unlessを使います。

flag = false

unless flag
    puts "condition true"
else
    puts "condition false"
end

少し読みやすくなったような気がします。

2.conditions(if/unless)を使用する際、1行で書けるなら1行で書く

flag = false

unless flag
    puts "condition true"
end

このように1行で書けるそうなものは1行で書きます。

flag = false

puts "condition true" unless flag

行数は減りましたが、若干読みづらい気がします。

3.if式のconditionにnilを使わない

RubynilPythonでのNoneだと認識しています。

input = ""

if input != nil
    puts "condition true"
else
    puts "condition false"
end

nilを使わないようにします。

input = ""

if input
    puts "condition true"
else
    puts "condition false"
end

読みやすくなりましたね。

4.ショートサーキットを利用した変数代入

# この前処理でユーザーからの入力を受け取る可能性があることが前提
user_input ||= ""

if user_input
    puts user_input
else
    puts "please your input"
end

なかなか使いどころが難しそうです。

5.変数の代入に、if式を利用する

Rubyのifは式なので、値を返します。その性質を利用してを変数の代入に利用します

flag = true

if flag
  result = "condition true"
else
  result = "condition false"
end

puts result

これはこうなります。

flag = true

result = if flag
  "condition true"
else
  "condition false"
end

puts result

resultへの代入が1つの式で済んでいるので、スマートになった気がします。

6.メソッド内でreturnをわざわざ明記しない

これはうっかりやってしまいそうです。

flag = true

def get_condition(flag)
  return_value = "condition init"
  if flag
    return_value = "condition true"
  else
    return_value = "condition false"
  end
  return return_value
end

puts get_condition(flag)

これはこうなります。

flag = true

def get_condition(flag)
  if flag
    "condition true"
  else
    "condition false"
  end
end

puts get_condition(flag)

すっきりして読みやすくなりました。

7.ショートサーキットを利用して、コードを短くする

A || B はAがtrueならAを返して、そうでなければ Bを返します。
その性質を利用するとコードが短くなります。

adventure_target = "hoge island"

def result_adventure(treasure_target)
  result = adventure_result(treasure_target)
  if result
    result
  else
    "treasure not found"
  end
end

puts result_adventure(adventure_target)
adventure_target = "hoge island"

def result_adventure(treasure_target)
  adventure_result(treasure_target) || "treasure not found"
end

puts result_adventure(adventure_target)

行数は減りましたが、またもや少し読みづらくなったような…

現在の所感

Rubyはなるべく変数を定義せず、1行当たりの処理量を増やすのかな、といったイメージです。
まだ続きのRubyBitsコースはあるのですが、有料なので、それをネタに記事を書いていいのか悩む…
いや、よくない! フリーコンテンツを探しに行こう!
僕のRuby道はこれからだ!!