Skip to content

Instantly share code, notes, and snippets.

@sambostock
Created June 22, 2020 10:42
Show Gist options
  • Save sambostock/1dc7937399c9ed32c3beee5e45463ccc to your computer and use it in GitHub Desktop.
Save sambostock/1dc7937399c9ed32c3beee5e45463ccc to your computer and use it in GitHub Desktop.
Unexpected behaviour with Ruby's rescue allowing calling of any setter method instead of local variable assignment.
explicit_receiver = Object.new
def explicit_receiver.setter=(error)
puts "setter= called with #{error.class}"
end
begin
1 / 0
rescue => explicit_receiver.setter
# There doesn't seem to be a restriction on rescue setting local variables.
# Ruby seems to take whatever appears in the rescue clause
# rescue => ____
# and use it to run
# ____ = error
# which then follows normal assignment semantics:
# - assigns local variable unless explicit receiver
# - sends ____= message to said receiver
end
# This can be turned into the following monstrosity
# Assuming you're using an error reporting framework like Bugsnag
# and it has an API like this:
module Bugsnag
def self.notify(error)
puts "\n\nW͇̖̮̰̘͛̉̏̏̌̚h̫̬̺̫̞̅̓a̡̞͇̪̖̜̲̎͐t́̓ͣͥͪ҉̣̜͔ ̼̟̖̈ͭh̵͕̙̭̠̭̀͋a̪̳ͯv̬̺̟̤̯̼̫̀̓͊̒̓̂e͙͈͗ͭͮͫͤͦͩ̀ ͈̹ͥ͋ͫ̄͛͒ͬI͉͖͇̫̳̤̟ͤ͆̉ ̲̹̮̩̤̭ͨ͗̾ͣ̍̉̓d͆̕ȯ̺̩͍ͭ͒ͯ̿ͅn̻͖͎̲̒͟e̜̽̌͌ͯ̾̚͟?͎\n\n"
end
end
# You can do
Bugsnag.singleton_class.alias_method :notify=, :notify
# and then
begin
1 / 0
rescue => Bugsnag.notify
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment