Hi,

At Sat, 27 Sep 2008 01:19:37 +0900,
Roger Pack wrote in [ruby-core:18981]:
> >> Yeah I was thinking it would be less confusing to only have one
> >> function name [source_location] and have it apply to both proc and
> >> method.
> >
> > Meanwhile, I added the methods without changing the function
> > names.  The names are another story.
> >
> > # I've thought I'd committed it already, but forgotten.
> 
> Thanks for adding those.  I see them in SVN now.
> I prefer #source_location but #location is livable :)

Methods are #source_location, C functions are still
*_location().

> >> Also note that it was mentioned that Binding#source_location would be
> >> nice--I just have no idea how to add it so the current patch doesn't
> >> include it.
> >
> > What is the line number of Binding?
> 
> There isn't one in that patch.  I'm unsure how to create Binding#source_location

It's easy to implement, if it is OK to return the beginning of
the code block where the binding was made.


Index: proc.c =================================================================== --- proc.c (revision 19593) +++ proc.c (working copy) @@ -29,4 +29,5 @@ static VALUE bmcall(VALUE, VALUE); static int method_arity(VALUE); static VALUE rb_obj_is_method(VALUE m); +static VALUE iseq_location(rb_iseq_t *iseq); /* Proc */ @@ -339,4 +340,22 @@ bind_eval(int argc, VALUE *argv, VALUE b } +/* + * call-seq: + * binding.source_location => [String, Fixnum] + * + * returns the ruby source filename and line number containing this binding + * or nil if this binding was not defined in ruby (i.e. native) + */ +VALUE +rb_bind_location(VALUE self) +{ + rb_binding_t *bind; + rb_env_t *env; + + GetBindingPtr(self, bind); + GetEnvPtr(bind->env, env); + return iseq_location(env->block.iseq); +} + static VALUE proc_new(VALUE klass, int is_lambda) @@ -1923,4 +1942,5 @@ Init_Binding(void) rb_define_method(rb_cBinding, "dup", binding_dup, 0); rb_define_method(rb_cBinding, "eval", bind_eval, -1); + rb_define_method(rb_cBinding, "source_location", rb_bind_location, 0); rb_define_global_function("binding", rb_f_binding, 0); } Index: ruby.c =================================================================== --- ruby.c (revision 19593) +++ ruby.c (working copy) @@ -1478,4 +1478,5 @@ ruby_prog_init(void) rb_define_global_const("ARGV", rb_argv); + rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new()); #ifdef MSDOS Index: vm.c =================================================================== --- vm.c (revision 19594) +++ vm.c (working copy) @@ -1241,7 +1241,4 @@ rb_iseq_eval(VALUE iseqval) vm_set_top_stack(th, iseqval); - if (!rb_const_defined(rb_cObject, rb_intern("TOPLEVEL_BINDING"))) { - rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new()); - } val = vm_exec(th); tmp = iseqval; /* prohibit tail call optimization */
-- Nobu Nakada