truthy
という単語は英和辞書には載っていない。ネットで英英辞書もいくつか見てみたが載っていなかった。
true
っぽい、というような意味だと思ってはいたが、きちんと調べたことがなかったので調べてみた。
この言葉を知ったきっかけは、Minitest の refute
のエラーメッセージだ。Minitest と test-unit の refute
、Rails の assert_not
は動きとしては同じなので、truthy
は「真」という意味だと思った。
Minitest refute
のエラーメッセージ
Expected #<Blog:0x00007f9da82c2a20> to not be truthy.
オブジェクトは truthy でないことが期待されています。
test-unit refute
のエラーメッセージ
<#<Blog:0x00007f973c845ff0>> is neither nil or false.
オブジェクトは nil でも false でもありません。
ActiveSupport(Rails)assert_not
のエラーメッセージ
Expected #<Blog:0x00007f9da82c1440> to be nil or false
オブジェクトは nil または false であることが期待されています
truthy とは?
JavaScript において、 truthy は Boolean コンテキストに現れた時に true とみなされる値のことです。 falsy として定義された値 (つまり、false, 0, -0, 0n, "", null, undefined, NaN) を除くすべての値は truthy です。
Truthy - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDNS
truthy
で検索したら最初にこれが出てきた。JavaScript の話だけど参考になりそう。Ruby では nil
と false
以外は「真」。やっぱり truthy
は、この「真」という意味のようだ。
ただ、引っかかるのがこれ。assert_not
の定義部分に書いてあるコメントだ。
rails/assertions.rb at 77932446895bd70f38a3aaa1ab288bf8a7b7142c · rails/rails · GitHub
# Asserts that an expression is not truthy. Passes if <tt>object</tt> is # +nil+ or +false+. "Truthy" means "considered true in a conditional" # like <tt>if foo</tt>. # # assert_not nil # => true # assert_not false # => true # assert_not 'foo' # => Expected "foo" to be nil or false # # An error message can be specified. # # assert_not foo, 'foo should be false' def assert_not(object, message = nil) message ||= "Expected #{mu_pp(object)} to be nil or false" assert !object, message end
表現が truthy ではないことを主張します。オブジェクトが nil か false の場合にパスするのです。"truthy" は if foo のように "条件付きで true とみなされる" ことを意味します。
先日も書いたのだが、DeepLさんで訳すとこんな感じになった。
truthy
が「真」という意味だったら、Ruby において下の2つは同じ意味になるはずだ。
- オブジェクトは truthy でないことが期待されています
- オブジェクトは nil または false であることが期待されています
truthy でない => 「真」でない => 偽である => nil または false である
どこが問題なのかわからない。
ところで、refute
の反対のassert
はどうなっているだろうと思って調べてみた。
class BlogTest < ActiveSupport::TestCase test "assertのテスト" do obj = nil assert obj end end
Rails(ActiveSupport)のテストを失敗させてエラー文を見てみた。truthy
が入っている!
Expected nil to be truthy.
assert
メソッドの定義場所を調べたら Minitest だった。こちらは assert_not
とは違い ActiveSupport では定義されていないようだ(つまりスーパークラスの Minitest のメソッドがそのまま使われる)。
minitest/assertions.rb at master · seattlerb/minitest · GitHub
# Fails unless +test+ is truthy. def assert test, msg = nil self.assertions += 1 unless test then msg ||= "Expected #{mu_pp test} to be truthy." msg = msg.call if Proc === msg raise Minitest::Assertion, msg end true end
結局、assert
は Minitest のがそのまま使われていて、assert_not
はエイリアスでもなくわざわざ ActiveSupport で定義されているということしかわからなかった。これからassert_not
の歴史を調べる予定なので、そこで何かわかるかもしれない。
まとめ(まとまってない)
truthy
について自分なりにまとめると以下のようになる(が、全然自信はない)。
truthy
は、true
っぽいというような意味で、「真」という意味合いで使われることもあるが、正確には「条件付きでRuby ではあまり使わない言葉(JavaScript と違って Ruby ドキュメントでは 英語版/日本語版 どちらにも出てこないので)。true
となる」という意味であり、
ここまで書いて気づいた。「条件付きでtrue
となる」は "considered true in a conditional" の訳のつもりだが、これって「真偽判定するとtrue
になる」って意味なのでは?
conditional に a がついているということは名詞っぽい。名詞だと「条件文」という意味がある!エラーメッセージを変えたいから別で定義したと思い込んでたときに訳したので先入観があったかもしれない。
Asserts that an expression is not truthy. Passes if object is nil or false. "Truthy" means "considered true in a conditional" like if foo.
式が truthy(真)でないことを明らかにします。オブジェクトが nil か false の場合にパスします。"truthy(真)"は if foo のように "条件文で true とみなされる" ことを意味します。
が正解かも!エラーメッセージは単により明確にしただけのことかもしれない。DeepLさんにはいつもお世話になってるけどやっぱり英語の勉強も大事。
となるとやはりtruthy
は「真」という意味でよさそう。もし違ったら教えてください。お願いします。