Project

General

Profile

Actions

Feature #14230

closed

Binding#source_location

Added by mame (Yusuke Endoh) about 7 years ago. Updated about 7 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:84435]

Description

How about providing Binding#source_location?

b = binding
p binding.source_location #=> ["test.rb", 1]

To fetch the information, people uses a dirty idiom: eval("[__FILE__, __LINE__]", binding).

I noticed this issue when changing the semantics of eval so that it does not inherit __FILE__ from the binding. [#4352]

diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index 9ce84b60fa..5216520f32 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -108,7 +108,7 @@ def filter_backtrace(bt)
     end
 
     def code_around_binding
-      file, pos = @binding.eval('[__FILE__, __LINE__]')
+      file, pos = @binding.source_location
 
       unless defined?(::SCRIPT_LINES__[file]) && lines = ::SCRIPT_LINES__[file]
         begin
diff --git a/proc.c b/proc.c
index 9dbc78ae4a..23c4d3a2d4 100644
--- a/proc.c
+++ b/proc.c
@@ -12,6 +12,7 @@
 #include "eval_intern.h"
 #include "internal.h"
 #include "gc.h"
+#include "vm_core.h"
 #include "iseq.h"
 
 /* Proc.new with no block will raise an exception in the future
@@ -611,6 +612,24 @@ bind_receiver(VALUE bindval)
     return vm_block_self(&bind->block);
 }
 
+/*
+ *  call-seq:
+ *     binding.source_location  -> [String, Integer]
+ *
+ *  Returns the Ruby source filename and line number of the binding object.
+ */
+static VALUE
+bind_location(VALUE bindval)
+{
+    VALUE loc[2];
+    const rb_binding_t *bind;
+    GetBindingPtr(bindval, bind);
+    loc[0] = pathobj_path(bind->pathobj);
+    loc[1] = INT2FIX(bind->first_lineno);
+
+    return rb_ary_new4(2, loc);
+}
+
 static VALUE
 cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda)
 {
@@ -3223,5 +3242,6 @@ Init_Binding(void)
     rb_define_method(rb_cBinding, "local_variable_set", bind_local_variable_set, 2);
     rb_define_method(rb_cBinding, "local_variable_defined?", bind_local_variable_defined_p, 1);
     rb_define_method(rb_cBinding, "receiver", bind_receiver, 0);
+    rb_define_method(rb_cBinding, "source_location", bind_location, 0);
     rb_define_global_function("binding", rb_f_binding, 0);
 }

Updated by shevegen (Robert A. Heiler) about 7 years ago

I like introspection so I am usually in agreement with all ways
to inspect ruby's behaviour.

+1

I also agree that eval-binding is not pretty.

Actions #3

Updated by mame (Yusuke Endoh) about 7 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r61480.


proc.c (bind_location): Add Binding#source_location

Fixes #14230

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy