From: Charlton Wang Date: 2012-02-02T13:49:56+09:00 Subject: [ruby-core:42320] [ruby-trunk - Bug #5930] source_location of blocks incorrect Issue #5930 has been updated by Charlton Wang. Yusuke Endoh wrote: > Hello, > > 2012/1/26 Charlton Wang : > > ----- > > def foo(*args, &block) > > �� ��p block.source_location > > end > > > > foo(1, > > �� ��2, > > �� ��3) do > > end > > ----- > > > > Under ruby 1.9.1-p243: ["-", 8] > > > > Under ruby 1.9.2-p136 and newer: ["-", 5] > > > > It seems with newer versions of ruby, it reports it based on the line on which the function is called instead of where the actual block is. I believe the old behaviour is actually the correct behaviour. > > > Do you really like the old behavior? Line 8 points > the end of the block. I prefer the beginning (Line 7). > IOW, a result I expect is: ["-", 7] I think the old behaviour will point you to the first line *after* the do. I agree that line 7 would be better abut at least line 8 is deterministic. > The following patch works for me, and passes test-all, > though I'm not sure if the fix is right. I'll commit > it if there is no objection. > > > diff --git a/parse.y b/parse.y > index 1ad9d62..428b942 100644 > --- a/parse.y > +++ b/parse.y > @@ -2798,7 +2798,6 @@ primary : literal > /*%%%*/ > $2->nd_iter = NEW_FCALL($1, 0); > $$ = $2; > - fixpos($2->nd_iter, $2); > /*% > $$ = method_arg(dispatch1(fcall, $1), arg_new()); > $$ = method_add_block($$, $2); > @@ -2811,7 +2810,6 @@ primary : literal > block_dup_check($1->nd_args, $2); > $2->nd_iter = $1; > $$ = $2; > - fixpos($$, $1); > /*% > $$ = method_add_block($1, $2); > %*/ > diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb > index 686db84..3deb5c0 100644 > --- a/test/ruby/test_proc.rb > +++ b/test/ruby/test_proc.rb > @@ -1059,6 +1059,20 @@ class TestProc < Test::Unit::TestCase > assert_equal(@@line_of_attr_accessor_source_location_test, lineno) > end > > + def block_source_location_test(*args, &block) > + block.source_location > + end > + > + def test_block_source_location > + exp_lineno = __LINE__ + 3 > + file, lineno = block_source_location_test(1, > + 2, > + 3) do > + end > + assert_match(/^#{ Regexp.quote(__FILE__) }$/, file) > + assert_equal(exp_lineno, lineno) > + end > + > def test_splat_without_respond_to > def (obj = Object.new).respond_to?(m,*); false end > [obj].each do |a, b| > > -- > Yusuke Endoh Thanks for the patch! Charlton ---------------------------------------- Bug #5930: source_location of blocks incorrect https://bugs.ruby-lang.org/issues/5930 Author: Charlton Wang Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: 1.9.2-p136 and newer Similar to bug #2427 but maybe the opposite problem. Newer versions of ruby appear to store the source locations of blocks incorrectly when passed as an argument to a multi-line invocation of a function. Snippet of code below reveals the problem: ----- def foo(*args, &block) p block.source_location end foo(1, 2, 3) do end ----- Under ruby 1.9.1-p243: ["-", 8] Under ruby 1.9.2-p136 and newer: ["-", 5] It seems with newer versions of ruby, it reports it based on the line on which the function is called instead of where the actual block is. I believe the old behaviour is actually the correct behaviour. Charlton -- http://bugs.ruby-lang.org/