Class: CallWith

Inherits:
Object
  • Object
show all
Defined in:
lib/callwith.rb

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/callwith.rb', line 28

def method_missing(method, *args, &block)
  obj = __callwith__obj__()
  self_obj = __callwith__self_obj__()

  if obj.respond_to?(method)
    obj.__send__(method, *args, &block)
  else
    self_obj.__send__(method, *args, &block)
  end
end

Class Method Details

.create(obj, self_obj) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'ext/callwith_ext.c', line 6

static VALUE callwith_s_create(VALUE klass, VALUE obj, VALUE self_obj)
{
  /* Create a new CallWith object, bypassing the usual object creation,
   * because the CallWith class is not a normal class. */
  NEWOBJ(with, struct RObject);
  OBJSETUP(with, klass, T_OBJECT);
  VALUE self = (VALUE)with;

  /* Place our delegate objects into the singleton class so we can
   * access them later */
  VALUE s = rb_singleton_class(self);
  rb_iv_set(s, "__with_obj__", obj);
  rb_iv_set(s, "__with_self_obj__", self_obj);

  /* Copy the pointer to the instance variable table from self_obj.  As
   * long as we hold a reference to self_obj, this pointer should be
   * valid. */
  struct RBasic basic = *(RBASIC(self));
  *(ROBJECT(self)) = *(ROBJECT(self_obj));
  *(RBASIC(self)) = basic;

  return self;
}

Instance Method Details

#__callwith__cleanup__Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'ext/callwith_ext.c', line 40

static VALUE callwith_cleanup(VALUE self)
{
  /* We don't want to keep the ivar table pointer around indefinitely,
   * because if we do, the GC will free the ivar table, which is
   * undesirable, since the original object still references it.  So we
   * set the ivar table back to something that won't get freed, instead.
   */

  NEWOBJ(dummy, struct RObject);
  OBJSETUP(dummy, rb_cCallWith, T_OBJECT);

  struct RBasic basic = *(RBASIC(self));
  *(ROBJECT(self)) = *(ROBJECT(dummy));
  *(RBASIC(self)) = basic;
}

#__callwith__obj__Object



30
31
32
33
# File 'ext/callwith_ext.c', line 30

static VALUE callwith_obj(VALUE self)
{
  return rb_iv_get(rb_singleton_class(self), "__with_obj__");
}

#__callwith__self_obj__Object



35
36
37
38
# File 'ext/callwith_ext.c', line 35

static VALUE callwith_self_obj(VALUE self)
{
  return rb_iv_get(rb_singleton_class(self), "__with_self_obj__");
}

#__instance_eval__Object