Class: Method

Inherits:
Object show all
Includes:
MethodAsCode, MethodAsExpression, MethodSig
Defined in:
lib/as_code.rb,
lib/methodsig.rb,
lib/as_expression.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MethodAsExpression

#as_expression

Methods included from MethodSig

#argument_info, #argument_names, #block_arg, #origin, #rest_arg

Methods included from MethodAsCode

#as_code

Class Method Details

.load(String) ⇒ Method

Load a Method from a String.



797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
# File 'ext/nodewrap.c', line 797

static VALUE method_load(VALUE klass, VALUE str)
{
  struct METHOD * method;
  VALUE rarr = marshal_load(str);
  VALUE * arr;
  NODE * n;
  VALUE retval;

  if(   ruby_safe_level >= 4
     || (ruby_safe_level >= 1 && OBJ_TAINTED(str)))
  {
    /* no playing with knives in the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't load method");
  }

  Check_Type(rarr, T_ARRAY);
  if(RARRAY_LEN(rarr) != 6)
  {
    rb_raise(rb_eArgError, "corrupt data");
  }

  /* Create a METHOD object -- doesn't matter which method we use */
  retval = rb_funcall(
      rb_cObject, rb_intern("method"), 1, ID2SYM(rb_intern("__id__")));
  Data_Get_Struct(retval, struct METHOD, method);
  arr = RARRAY_PTR(rarr);
  method->klass =
    rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[0]);
#if RUBY_VERSION_CODE >= 180
  method->rklass =
    rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[1]);
#else
  method->oklass =
    rb_funcall(lookup_module_proc, rb_intern("call"), 1, arr[1]);
#endif
  method->recv = arr[2];
  method->id = SYM2ID(arr[3]);
  method->oid = SYM2ID(arr[4]);
  Data_Get_Struct(arr[5], NODE, n);
  method->body = n;

  if(klass == rb_cUnboundMethod)
  {
    retval = rb_funcall(retval, rb_intern("unbind"), 0);
  }

  return retval;
}

Instance Method Details

#dump(limit) ⇒ String

Dump a Method and the object to which it is bound to a String. The Method’s class will not be dumped, only the name of the class.

Unfortunately, this means that methods for anonymous classes can be dumped but cannot be loaded.



757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
# File 'ext/nodewrap.c', line 757

static VALUE method_dump(VALUE self, VALUE limit)
{
  struct METHOD * method;
  VALUE arr;

  if(ruby_safe_level >= 4)
  {
    /* no access to potentially sensitive data from the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't dump method");
  }

  arr = rb_ary_new();
  Data_Get_Struct(self, struct METHOD, method);
  rb_ary_push(arr, rb_mod_name(method->klass));
#if RUBY_VERSION_CODE >= 180
  rb_ary_push(arr, rb_mod_name(method->rklass));
#else
  rb_ary_push(arr, rb_mod_name(method->oklass));
#endif
  if(rb_class_of(self) == rb_cUnboundMethod)
  {
    rb_ary_push(arr, Qnil);
  }
  else
  {
    rb_ary_push(arr, method->recv);
  }
  rb_ary_push(arr, ID2SYM(method->id));
  rb_ary_push(arr, ID2SYM(method->oid));
  rb_ary_push(arr, method_body(self));

  return marshal_dump(arr, limit);
}

#bodyNode

Given a Method, returns the Node for that Method’s body. This can be used to directly copy one class’s method to another (using add_method).



735
736
737
738
739
740
741
742
743
744
745
# File 'ext/nodewrap.c', line 735

static VALUE method_body(VALUE method)
{
  struct METHOD * m;
  if(ruby_safe_level >= 4)
  {
    /* no access to potentially sensitive data from the sandbox */
    rb_raise(rb_eSecurityError, "Insecure: can't get method body");
  }
  Data_Get_Struct(method, struct METHOD, m);
  return wrap_node(m->body);
}

#method_idSymbol

Given a Method, returns the Symbol of the method it represents. If the method is an alias for another method, returns the Symbol of the new method, not the original. If the method changes name, returns the original name, not the new name.



684
685
686
687
688
689
# File 'ext/nodewrap.c', line 684

static VALUE method_id(VALUE method)
{
  struct METHOD * m;
  Data_Get_Struct(method, struct METHOD, m);
  return ID2SYM(m->id);
}

#method_oidSymbol

Given a Method, returns the Symbol of the method it represents. If the method is an alias for another method, returns the Symbol of the original method, not the alias. If the original method changes name, returns the original name.



700
701
702
703
704
705
# File 'ext/nodewrap.c', line 700

static VALUE method_oid(VALUE method)
{
  struct METHOD * m;
  Data_Get_Struct(method, struct METHOD, m);
  return ID2SYM(m->oid);
}

#origin_classClass

Given a Method, returns the Class in which the method it represents was defined. If the method was defined in a base class and Object#method is called on a derived instance of that base class, this method returns the base class.



716
717
718
719
720
721
722
723
724
725
# File 'ext/nodewrap.c', line 716

static VALUE method_origin_class(VALUE method)
{
  struct METHOD * m;
  Data_Get_Struct(method, struct METHOD, m);
#if RUBY_VERSION_CODE < 180
  return m->oklass;
#else
  return m->rklass;
#endif
}

#receiverObject

Given a Method, returns the Object to which it is bound.



668
669
670
671
672
673
# File 'ext/nodewrap.c', line 668

static VALUE method_receiver(VALUE method)
{
  struct METHOD * m;
  Data_Get_Struct(method, struct METHOD, m);
  return m->recv;
}

#signatureObject

Return a String representing the method’s signature.



201
202
203
204
205
206
207
# File 'lib/methodsig.rb', line 201

def signature
  return Signature.new(
      origin_class() || attached_class(),
      method_oid().to_s,
      argument_names(),
      argument_info)
end