Method: Object#singleton_method

Defined in:
proc.c

#singleton_method(sym) ⇒ Object

Similar to method, searches singleton method only.

class Demo
  def initialize(n)
    @iv = n
  end
  def hello()
    "Hello, @iv = #{@iv}"
  end
end

k = Demo.new(99)
def k.hi
  "Hi, @iv = #{@iv}"
end
m = k.singleton_method(:hi)
m.call   #=> "Hi, @iv = 99"
m = k.singleton_method(:hello) #=> NameError


2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
# File 'proc.c', line 2139

VALUE
rb_obj_singleton_method(VALUE obj, VALUE vid)
{
    VALUE sc = rb_singleton_class_get(obj);
    VALUE klass;
    ID id = rb_check_id(&vid);

    if (NIL_P(sc) ||
        NIL_P(klass = RCLASS_ORIGIN(sc)) ||
        !NIL_P(rb_special_singleton_class(obj))) {
        /* goto undef; */
    }
    else if (! id) {
        VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
        if (m) return m;
        /* else goto undef; */
    }
    else {
        VALUE args[2] = {obj, vid};
        VALUE ruby_method = rb_rescue(rb_obj_singleton_method_lookup, (VALUE)args, rb_obj_singleton_method_lookup_fail, Qfalse);
        if (ruby_method) {
            struct METHOD *method = (struct METHOD *)RTYPEDDATA_GET_DATA(ruby_method);
            VALUE lookup_class = RBASIC_CLASS(obj);
            VALUE stop_class = rb_class_superclass(sc);
            VALUE method_class = method->iclass;

            /* Determine if method is in singleton class, or module included in or prepended to it */
            do {
                if (lookup_class == method_class) {
                    return ruby_method;
                }
                lookup_class = RCLASS_SUPER(lookup_class);
            } while (lookup_class && lookup_class != stop_class);
        }
    }

  /* undef: */
    vid = ID2SYM(id);
    rb_name_err_raise("undefined singleton method '%1$s' for '%2$s'",
                      obj, vid);
    UNREACHABLE_RETURN(Qundef);
}