Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created October 27, 2022 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/8cb581a778bef7a5260f9d19b02a8ef0 to your computer and use it in GitHub Desktop.
Save JoshCheek/8cb581a778bef7a5260f9d19b02a8ef0 to your computer and use it in GitHub Desktop.
NameError::message
require "objspace"
# A name error
err = omg rescue $!
err # => #<NameError: undefined local variable or method `omg' for main:Object>
# The error has a message object instead of a message string
# this object is a secret internal class with an invalid constant name
_, message, * = ObjectSpace.reachable_objects_from err
message # => #<NameError::message:0x000000015590b608>
# The message has access to `main`, since that's the object the missing method was called on
ObjectSpace.reachable_objects_from message
# => [NameError::message,
# "undefined local variable or method `%s' for %s%s%s",
# main]
# The message will be coerced into a string b/c it has a `to_str` method
message.to_str # => "undefined local variable or method `omg' for main:Object"
# That method is calculated lazily (b/c it's potentially extremely expensive)
define_singleton_method(:inspect) { "OMGHI" }
message.to_str # => "undefined local variable or method `omg' for OMGHI:Object"
# We could do the same thing ourselves:
i = -1
message = -> { "count: #{i+=1}" }
message.instance_eval { alias to_str call }
err = RuntimeError.new message
err # => #<RuntimeError: count: 0>
err.message # => "count: 1"
err.message # => "count: 2"
err.message # => "count: 3"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment