From: "byroot (Jean Boussier) via ruby-core" Date: 2026-02-05T20:29:06+00:00 Subject: [ruby-core:124692] [Ruby Bug#21864] Inconsistencies in type coercion error messages for integers Issue #21864 has been updated by byroot (Jean Boussier). I'm working a a small refactor: https://github.com/ruby/ruby/pull/16078 I have to battle a bit with some test assertions, but it's pretty simple. ---------------------------------------- Bug #21864: Inconsistencies in type coercion error messages for integers https://bugs.ruby-lang.org/issues/21864#change-116285 * Author: herwin (Herwin W) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux], but consisten since at least Ruby 3.2, haven't checked older releases * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Some context in https://github.com/ruby/spec/pull/1345, all code snippets are run using Ruby 4.0.1 on a 64bit Linux (Debian) system, unless stated otherwise. Ruby has some generic type coercion error message. For example: ```ruby File.truncate(var, 1) ``` Depending on the type of `var`, it can generate error messages like: ``` no implicit conversion of Integer into String (TypeError) no implicit conversion of false into String (TypeError) ``` In general `true`, `false` and `nil` print the string representation of the object, anything else prints the class of the object. One could argue that this is inconsistent, but it's probably better than printing `NilClass` in the error (something I've recently seen happen in Natalie and TruffleRuby, I would guess JRuby occasionally has this issue as well, but I haven't looked for it. The exact error messages are often missing in the Ruby specs). The conversion to integer is weird. ```ruby File.truncate("/dev/zero", var) ``` Anything other than `nil` gets pretty much the same output as before: ``` no implicit conversion of Symbol into Integer (TypeError) no implicit conversion of false into Integer (TypeError ``` But this is where nil has a special path: ``` no implicit conversion from nil to integer (TypeError) ``` Now it's usng "from .. to" instead of "of .. into", and `integer` is written in lower case. But, this message is not consistent either, based on the size of `off_t`, where the coercion uses either `rb_num2long` or `rb_num2ll`, which have different checks for `nil`: ```c // Taken from commit 86dba8cfaeabb3b86df921da24b3243b9ce4ab2a long rb_num2long(VALUE val) { again: if (NIL_P(val)) { rb_raise(rb_eTypeError, "no implicit conversion from nil to integer"); } LONG_LONG rb_num2ll(VALUE val) { if (NIL_P(val)) { rb_raise(rb_eTypeError, "no implicit conversion from nil"); } ``` That last one has some internal checks for other types, with more inconsistent error messages: ```c rb_raise(rb_eTypeError, "no implicit conversion from string"); rb_raise(rb_eTypeError, "no implicit conversion from boolean"); ``` That last one looks like the only error message to mention the term `boolean`. IMHO the first message type is the clearest, so I would propose to write every coercion failure in this way: ```ruby type = value.nil? || value == true || value == "false" ? value.inspect : value.class klass = "String" # Or Integer, or ... "no implicit conversion of #{type} into #{klass}" ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/