大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【無職に転生 ~ 就職するまで毎日ブログ出す_22】【Ruby】リテラルなどの不思議な書き方集

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はRubyKaigiやAtcorderなどで出される問題から引用してRubyの不思議な書き方を理解する記事です。プログラミングのコードの書き方は本当に様々で、Rubyに至っても約1年間勉強していますがいまだに不慣れな書き方がたくさんあります。ですがそこは地道に覚えていくしかありません。今回はリテラルなどを覚えていきたいと思います。

? リテラルと否定演算子三項演算子

それではまず最初に以下の文を見てみます。

irb> !????!:!?!

この問題はRubyKaigi 2019で出された問題のようです。!や?がたくさん並んでいて意味がわからないですよね。ですがこの問題はRubyの基礎知識だけで解くことができます。どう出力されるかわかりますか。答えはfalseが出力されます。

irb> !????!:!?!
=> false

この問題を解く上でのポイントは3つあります。

?リテラル

まず?リテラルですが、これはこの? が記載されているとその直後に書かれた1文字は文字列として出力されるというものです。

?あ
=> ""

文字の「あ」はコード上ではいつもクオーテーションで囲まなければいけませんが、?を直前につけることで文字列に変換することができます。これは自分は知らなかったです。

否定演算子

これはRailsでもよく使います。直後に書かれているオブジェクトの真偽値を入れ替えるものです。例えば、先ほどの文字列の「あ」はnilでもないので真偽値としてはtrueですが、否定演算子を直前に付けることでfalseと出力できます。

!?あ
=> false

Railsでは!!と否定演算子を2個付けることで、オブジェクトの真偽値を無理やりboolean方に変換することが多いですね。

!!?あ
=> true

三項演算子

if文の代わりとして使われることが多い構文です。if分はコードの行数を大きく増やします。elseが含まれるだけで5行も増えます。

hoge = nil
if hoge.nil?
    puts "a"
else
    puts "b"
end

上記のようにシンプルなifとelseの文は多くの箇所で使えると思います。しかし、少し冗長な気もしますよね。

そこで三項演算子の出番です。上記の文を以下のように置き換えることができます。

hoge = nil
puts hoge.nil? ? "a" : "b"

if文を経ったの1行で書けるようになりました。このようにシンプルなif else文は三項演算子に置き換える方がコードが簡潔になります。


以上3点を踏まえた上で問題のコードを解説します。

!????!:!?!

まず、?リテラルでどの文字が文字列として変換されているか確認します。まず1番に判別できるのは末端にある?!です。これは文字列「"!"」として出力されていますね。

!????!:!(?!)

次に?が4つ並んでいる部分ですがこれはどれが文字列に変換されるのかパッとみたところわかりづらいです。ここで三項演算子のことを思い出します。コードの中にがあるので、三項演算子が使われていることがわかるかなと思います。よって?4つのうちどれか一つは三項演算子として使われます。その条件を考えると文字列は以下のように変換されます。

!(??)?(?!):!(?!)

あとは否定演算子で文字列を真偽値に変換します。

false?"!":false

三項演算子falseの部分(:以降)が出力されるので、結果falseが出力されます。

こうして分解するとかなり簡単に理解できたかなと思います。ちなみにこの問題の難易度は1番簡単だったらしいです。。。まだまだ修行が足りないです。💦


%記法

%を使うことで文字列や配列を書くことができます。種類はかなり多いです。

  • %, %Q

ダブルクオーテーションと囲む場合と同じ意味になります。ダブルクオーテーションで囲んでいるので式展開ができます。

nums = %(789)
=> "789"
%(123 456 #{nums})
=> "123 456 789"

# 上と同じ記述
nums = "789"
=> "789"
"123 456 #{nums}"
=> "123 456 789"
  • %q

シングルクオーテーションと囲む場合と同じ意味になります。こちらはダブルクオーテーションではないので大丈夫です。

a = "sample"
=> "sample"
%q(a)
=> "a"

# 上と同じ記述
'a'
=> "a"
  • %s

シンボルを書く:と同じような書き方になります。

%s(SYMBOL)
=> :SYMBOL

# 上と同じ記述
:SYMBOL
=> :SYMBOL
  • %W

配列を書くための%記法になります。各要素は()の中で空白で区切ることができます。中の文字列はダブルクオーテーションで囲まれているので式展開ができます。

c = "hoge"
=> "hoge"
%W(a b #{c})
=> ["a", "b", "hoge"]
  • %w

こちらも配列を書くための%記法になります。しかし、各要素はシングルクオーテーションで囲まれているので式展開はできません。

c = "hoge"
=> "hoge"
%w(a b #{c})
=> ["a", "b", "\#{c}"]
  • %I

シンボルの配列を書くための%記法です。大文字なので式展開できます。

c = "hoge"
=> "hoge"
%I(a b #{c})
=> [:a, :b, :hoge]
  • %i

シンボルの配列を書くための%記法です。式展開できません。

c = "hoge"
=> "hoge"
%i(a b #{c})
=> [:a, :b, :"\#{c}"]

||=演算子

こちらは通称「nilガード」と言われている演算子です。もし変数の値が初期化されていないのであれば値を格納します。既に初期化されているならば新しい値は格納されずに値はそのままです。

foo ||= 'hoge'
=> 'hoge'
foo ||= 'fuga'
=> 'hoge'

&.演算子

こちらは通称「ぼっち演算子」と言われています。Rubyのメソッドは返却値がnilになっていることが多く、それによってnilクラスに定義されていないメソッドが実行されてしまいUndefined Method Errorになってしまうことがよくあるかと思います。

a = nil
a.upcase
# (undefined method `upcase' for nil:NilClass)

その時にぼっち演算子を使うと例外を回避できます。返り値は必ずnilとなります。

a = nil
a&.upcase
=> nil

参考記事

難読Rubyコードクイズ問題と解説 in RubyKaigi 2019 - エムスリーテックブログ

Rubyで%記法(パーセント記法)を使う - Qiita

Ruby初心者を脱した人が悩みがちな、ちょっと特殊な記法・演算子・イディオム - Qiita