From: Sylvester Keil Date: 2011-11-01T01:20:36+09:00 Subject: How to identify attribute reader methods Hello world, I'm currently working with the 'johnson' gem (a project that embeds Mozilla's spider/trace monkey JavaScript engine in Ruby) on Ruby 1.9 and encountered the compatibility issue outlined below. Among other cool features, johnson uses proxies for Ruby objects in JavaScript (and vice-versa), to allow for things like: > A = Class.new { attr_accessor :a; def f(x); x; end } > js['a'] = A.new > js.evaluate("var y = 42") > js.evaluate("a.f(y)") This (contrived) example assigns a Ruby object to a JavaScript variable ('a') and calls a method on the object. More to the point, you can also return the method object from JavaScript land by leaving of the parentheses just as with regular JavaScript functions: > js.evaluate("a.f") => # Now, johnson tries to treat Ruby instance variables (and attribute readers) like JavaScript object properties, so instead of a method object, ideally `js.evaluate("a.a")` ought to return nil (because the instance variable @a has not been set and 'a' is strictly an attribute reader defined by attr_accessor). This was achieved in the Johnson code by using the Data_Get_Struct macro to get the METHOD struct and subsequently check its node type in the struct's 'body' member like this: METHOD* method; Data_Get_Struct(rb_method, METHOD, method); if (method && nd_type(method->body) == NODE_IVAR) { return Qtrue; } (For this to work, the required definitions were copied from method.h to the johnson sources). This fails in 1.9 because the METHOD struct has changed considerably since 1.8. and I wonder how something similar could be achieved in 1.9. Is the method type VM_METHOD_TYPE_IVAR in rb_method_definition_t used to distinguish attribute readers? Or, to put my question more generally, is there an easy way to check for reader-type methods from Ruby or from a C extension without having to resort to internal structs which are not exported by default? That is to say, when you have a Method object, is there a way to check whether or not it was originally created by the attr_accessor or attr_reader generators? Thanks! Sylvester