Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where do Ruby exception instances keep their message?

Tags:

ruby

If I have an instance of StandardError, where is the message stored?

s = StandardError.new("hi")
s.message                          # => "hi"
s.instance_variables               # => []
s.instance_variable_get(:@message) # => nil
s.inspect                          # => "#<StandardError: hi>"
like image 668
Adam Avatar asked Sep 14 '25 14:09

Adam


2 Answers

In addition, be mindful that not all parts of Ruby are written in Ruby, especially for very base classes like Exception or StandardError.

You can find your answer by looking at the source of the message method on Exception class (click then go to the message method and use the small magnifying glass to show the source). This code is C, not Ruby.

like image 195
Martin Avatar answered Sep 17 '25 20:09

Martin


After some investigation into Ruby and C, I have found that the exception class sets an instance variable with the name of mesg. This cannot be accessed in the standard Ruby runtime because it does not start with an @.

It is possible to add a Ruby extension which will let you get and set instance variables that are not prefixed with @. I have no idea how dangerous this might be.

C Module:

#include "ruby.h"

static VALUE rb_mIvar;

static VALUE rb_ivar_iv_get(VALUE self, VALUE key) {
  return rb_ivar_get(self, rb_to_id(key));
}

static VALUE rb_ivar_iv_set(VALUE self, VALUE key, VALUE value) {
  return rb_ivar_set(self, rb_to_id(key), value);
}

void Init_ivar() {
  rb_mIvar = rb_define_module("Ivar");
  rb_define_method(rb_mIvar, "ivar_get", rb_ivar_iv_get, 1);
  rb_define_method(rb_mIvar, "ivar_set", rb_ivar_iv_set, 2);
}

Ruby usage:

$:.unshift('.')
require 'ivar'

Object.send(:include, Ivar)

e = StandardError.new("foo")

puts "Error message is: #{e.message}" # => e.message is "foo"

e.ivar_set(:mesg, "bar")

puts "Error message is: #{e.message}" # => e.message is now "bar"

See this gist with the full code I used to research and experiment: https://gist.github.com/adamhunter/5041075

like image 34
Adam Avatar answered Sep 17 '25 20:09

Adam