3

StandardError のインスタンスがある場合、メッセージはどこに保存されますか?

s = StandardError.new("hi")
s.message                          # => "hi"
s.instance_variables               # => []
s.instance_variable_get(:@message) # => nil
s.inspect                          # => "#<StandardError: hi>"
4

3 に答える 3

6

さらに、Ruby のすべての部分が Ruby で記述されているわけではないことに注意してください。特に、Exception や StandardError などの非常に基本的なクラスについては注意が必要です。

答えは、Exceptionクラスのメッセージ メソッドのソースを参照して見つけることができます (クリックしてメッセージ メソッドに移動し、小さな虫めがねを使用してソースを表示します)。このコードは Ruby ではなく C です。

于 2013-02-25T19:38:57.223 に答える
3

Ruby と C を調査した結果、例外クラスがmesg. これは . で始まらないため、標準の Ruby ランタイムではアクセスできません@

接頭辞が付いていないインスタンス変数を取得および設定できる Ruby 拡張機能を追加することができます@。これがどれほど危険なのか、私にはわかりません。

C モジュール:

#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);
}

ルビーの使い方:

$:.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"

私が調査と実験に使用した完全なコードを含むこの要点を参照してください: https://gist.github.com/adamhunter/5041075

于 2013-02-26T19:05:56.077 に答える
0

メソッドs.message # => "hi"を呼び出す呼び出しによって返されるメッセージ。to_s詳細: Ruby 例外

于 2013-02-25T19:34:44.417 に答える