💬

Ruby 3.3 では 'it' という形でメソッドを呼び出すと警告がでるようになる

2024/01/03に公開

ご存の方も多いと思いますが Numbered parameters で it をキーワードとして利用できるようにする提案が承認されました。

どういうことかと言うとブロック内では _1 の変わりに it というキーワードが利用できるようになります。

[1, 2, 3, 4, 5].map { it + it }

この機能は Ruby 3.4 で実装され、既存のコードと互換性がなくなるため Ruby 3.3 では警告が出るようになります。
警告が出るケースは『 it という名前でメソッドを呼び出した時』になります。
逆に言うと以下のように『変数を参照した場合』や『メソッドっぽく呼び出した場合』には警告はでません。

# 警告が出るケース

# ブロックの中で `it` 単体で参照した時
# warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it() or self.it
tap { it }

# warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it() or self.it
tap { it.nil? }
# 警告が出ないケース

# 同名のメソッドを定義しておく
def it(*)
end

# ブロックの外でのメソッド呼び出し
it

# ブロックの中で『メソッドぽく』メソッドを呼び出した場合
tap { it() }
tap { it 42 }
tap { it {} }
tap { it do end }
tap { self.it }

# 変数として定義されている場合
tap { |it| it }

it = 42
tap { it }

it というと RSpec で多用はされているんですが基本的にはブロックを渡して利用する事がほとんどだと思うので問題ないとは思います。

# it に引数やブロックを渡している書き方になるので問題ない
it { is_expected.to eq 42 }

it "正しく入力がされること" do
  # ...
end

逆に it というメソッドを定義していて it だけで呼び出している場合には Ruby 3.4 で互換性がなくなるので注意する必要があります。
また it_1 の違いとして同名のメソッドや変数が定義できるかどうかの違いがありそうです。

# it は同名の変数やメソッドが定義できる
it = 42

def it
end
# _1 は同名の変数やメソッドが定義できない

# error
_1 = 42

# error
def _1
end

個人的には it という名前はキーワードに見えないし、引き続きメソッド名としても利用できるという点では『 it がどういう意味を持つのかが曖昧になる』ので入ってはほしくなかったんですがまあ入っちゃったのはしょうがない。
わたしは引き続き _1 を使っていこうと思います。

GitHubで編集を提案

Discussion