Project

General

Profile

Actions

Feature #4840

closed

Allow returning from require

Added by rosenfeld (Rodrigo Rosenfeld Rosas) almost 13 years ago. Updated over 6 years ago.

Status:
Closed
Target version:
-
[ruby-core:36785]

Description

I have a situation where there is some code in Gitorious like:

unless defined? GitoriousConfig
  # tons of lines here
end

And I would it to look like

return if defined? GitoriousConfig

#tons of lines here

It would be great to allow return from a required file or some other keyword (break, etc or a new one)


Files

feature-4840.odp (114 KB) feature-4840.odp Slide for presentation to Matz rosenfeld (Rodrigo Rosenfeld Rosas), 06/08/2012 02:38 AM
0001-compile.c-toplevel-return.patch (1.71 KB) 0001-compile.c-toplevel-return.patch nobu (Nobuyoshi Nakada), 05/09/2013 11:14 AM

Related issues 4 (0 open4 closed)

Related to Ruby master - Bug #13678: toplevel return causes [BUG]ClosedActions
Related to Ruby master - Bug #13682: return inside of ensure causes [BUG]ClosedActions
Related to Ruby master - Bug #13755: Null pointer dereference in hash_table_index()ClosedActions
Related to Ruby master - Bug #14062: Top-level return allows an argumentClosedActions

Updated by judofyr (Magnus Holm) almost 13 years ago

I think using "return" is quite natural in this case, as long as we
can use it in module/class-definitions too.

// Magnus Holm

On Mon, Jun 6, 2011 at 16:18, Michael Edgar wrote:

On Jun 6, 2011, at 10:11 AM, Rodrigo Rosenfeld Rosas wrote:

It would be great to allow return from a required file or some other keyword (break, etc or a new one)

This could be implemented as a method that raises an exception that require and load rescue.
I'm not sure how compatible that would be with custom require implementations (rubygems,
polyglot, etc), but it would obviate the need for a new keyword or commandeering an existing one.

Michael Edgar

http://carboni.ca/

Updated by cjheath (Clifford Heath) almost 13 years ago

On 07/06/2011, at 12:18 AM, Michael Edgar wrote:

On Jun 6, 2011, at 10:11 AM, Rodrigo Rosenfeld Rosas wrote:

It would be great to allow return from a required file or some
other keyword (break, etc or a new one)

This could be implemented as a method that raises an exception that
require and load rescue.
I'm not sure how compatible that would be with custom require
implementations (rubygems,
polyglot, etc)

Polyglot will pass all exceptions except LoadError (or a subclass).
With a LoadError, if it has no further possibility to satisfy the
require,
the original exception is re-raised. Thus, polyglot should not impede
the implementation you propose.

Clifford Heath.

Updated by rkh (Konstantin Haase) almost 13 years ago

How will that work with require? Remember it will only load the file once. Return false otherwise? (Which would be kinda compatible with the current behavior and using raise/throw). Or should those values be cached? If you want to use require CommonJS-style, it has to be cached. But what about return values that depend on or provoke side effects? Should files support early return?

Konstantin

On Jun 7, 2011, at 00:08 , Clifford Heath wrote:

On 07/06/2011, at 12:18 AM, Michael Edgar wrote:

On Jun 6, 2011, at 10:11 AM, Rodrigo Rosenfeld Rosas wrote:

It would be great to allow return from a required file or some
other keyword (break, etc or a new one)

This could be implemented as a method that raises an exception that
require and load rescue.
I'm not sure how compatible that would be with custom require
implementations (rubygems,
polyglot, etc)

Polyglot will pass all exceptions except LoadError (or a subclass).
With a LoadError, if it has no further possibility to satisfy the
require,
the original exception is re-raised. Thus, polyglot should not impede
the implementation you propose.

Clifford Heath.

Updated by mame (Yusuke Endoh) almost 13 years ago

Hello,

2011/6/6 Rodrigo Rosenfeld Rosas :

I have a situation where there is some code in Gitorious like:

unless defined? GitoriousConfig
 # tons of lines here
end

And I would it to look like

return if defined? GitoriousConfig

#tons of lines here

It would be great to allow return from a required file or some other keyword (break, etc or a new one)

Agreed. It would be also useful to write platform-specific code:

require "test/unit"

return unless /mswin|cygwin|mingw|bccwin/

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 13 years ago

Em 07-06-2011 07:10, Yusuke ENDOH escreveu:

Hello,

...

Agreed. It would be also useful to write platform-specific code:

   require "test/unit"

   return unless /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM

   class TestForWindowsEnv<  Test::Unit::TestCase
   ...

Here is an experimental patch:

diff --git a/compile.c b/compile.c
index 10d63bc..7b9c490 100644
--- a/compile.c
+++ b/compile.c
@@ -4291,10 +4291,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR
*ret, NODE * node, int poped)
  	rb_iseq_t *is = iseq;

  	if (is) {
-	    if (is->type == ISEQ_TYPE_TOP) {
-		COMPILE_ERROR((ERROR_ARGS "Invalid return"));
-	    }
-	    else {
  		LABEL *splabel = 0;

  		if (is->type == ISEQ_TYPE_METHOD) {
@@ -4321,7 +4317,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR
*ret, NODE * node, int poped)
  			ADD_INSN(ret, nd_line(node), pop);
  		    }
  		}
-	    }
  	}
  	break;
        }
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index f40dfdf..274f45d 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1561,8 +1561,6 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
  		    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
  		}

-		rb_vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
-
  	      valid_return:
  		pt = dfp;
  	    }

This patch is so small, that it seems strange that it affects only
requires... Won't it have side effects? Notice that I didn't test it yet.

I agree with you about specific-platform tests use case too.

Thanks for your interest,

Rodrigo.

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 13 years ago

Em 07-06-2011 05:14, Haase, Konstantin escreveu:

How will that work with require? Remember it will only load the file once. Return false otherwise? (Which would be kinda compatible with the current behavior and using raise/throw). Or should those values be cached? If you want to use require CommonJS-style, it has to be cached. But what about return values that depend on or provoke side effects? Should files support early return?

I was thinking about that yesterday, but I have no idea how this should
work. If an aborted required should return true or false. Or a value
defined by the return, like:

return :aborted if should_abort?

Or if require should accept some block as:

require('some/file'){|return_value| do_something_with return_value }

Really, I have no idea about this!

Best regards,

Rodrigo.

Updated by mame (Yusuke Endoh) almost 13 years ago

Hello,

2011/6/7 Rodrigo Rosenfeld Rosas :

This patch is so small, that it seems strange that it affects only
requires... Won't it have side effects? Notice that I didn't test it yet.

I'm not sure.
But surprisingly, the patch passes all tests except one.

--
Yusuke Endoh

Updated by matz (Yukihiro Matsumoto) almost 13 years ago

Hi,

In message "Re: [ruby-core:36811] Re: [Ruby 1.9 - Feature #4840][Open] Allow returning from require"
on Tue, 7 Jun 2011 19:10:15 +0900, Yusuke ENDOH writes:

Agreed.

Ah, I understand the request. But returning from outside of a method
makes me so weird.

						matz.

Updated by headius (Charles Nutter) almost 13 years ago

On Tue, Jun 7, 2011 at 7:33 PM, Yukihiro Matsumoto wrote:

Ah, I understand the request.  But returning from outside of a method
makes me so weird.

I agree with both the feature and the fact that return outside a
method feels weird. An early termination of a loading file would be
welcome; I've wanted this many times, and always ended up doing the
super-gross "giant if" to accomplish what could be done by a simple
early exit.

I wonder if a core method that does the early return would be a better
option, like Kernel#exit_script. It could be implemented to throw an
exception all requires and loads expect to catch, like
"ExitScriptError" or something. That would seem more consistent than
having return end the script...but not actually be returning anything.

Another option would be to use a different keyword that isn't so tied
to method/proc bodies, like "break"

break if defined? GitoriousConfig

I think I like the exit_script version better, though.

exit_script if defined? GitoriousConfig
  • Charlie

Updated by aprescott (Adam Prescott) almost 13 years ago

On Wed, Jun 8, 2011 at 8:38 AM, Charles Oliver Nutter
wrote:

exit_script if defined? GitoriousConfig

This could be confusing, if you happen to view the entire program as a
script. You might think that "exit_script" will do the same thing as
"abort". I like the idea, though.

Updated by zenspider (Ryan Davis) almost 13 years ago

On Jun 7, 2011, at 17:33 , Yukihiro Matsumoto wrote:

Hi,

In message "Re: [ruby-core:36811] Re: [Ruby 1.9 - Feature #4840][Open] Allow returning from require"
on Tue, 7 Jun 2011 19:10:15 +0900, Yusuke ENDOH writes:

|Agreed.

Ah, I understand the request. But returning from outside of a method
makes me so weird.

How about raising a specific exception that is rescued by #require instead?

class AbortRequire < StandardError; end

alias :original_require :require

def require f
  original_require f
rescue AbortRequire
  false
end

def 

p require 'f' #

Updated by headius (Charles Nutter) almost 13 years ago

On Wed, Jun 8, 2011 at 4:22 AM, Ryan Davis wrote:

How about raising a specific exception that is rescued by #require instead?

class AbortRequire < StandardError; end

...

raise AbortRequire if defined? GitoriousConfig

That's pretty clean too. Name needs work ;)

I almost suggested a special catch tag that all requires wrap, but
catch/throw is a little arcane for most folks...

  • Charlie

Updated by regularfry (Alex Young) almost 13 years ago

On 08/06/11 01:33, Yukihiro Matsumoto wrote:

Hi,

In message "Re: [ruby-core:36811] Re: [Ruby 1.9 - Feature #4840][Open] Allow returning from require"
on Tue, 7 Jun 2011 19:10:15 +0900, Yusuke ENDOH writes:

Agreed.

Ah, I understand the request. But returning from outside of a method
makes me so weird.

To me, return would imply that the returned value should be passed back
by the original require call, like so:

$ cat a.rb
return 42

$ cat b.rb
p require("a")

$ ruby -I. b.rb
42

That could be really handy, although it's not compatible with my
previous suggestion (currently languishing here:
http://redmine.ruby-lang.org/issues/4523 - any comments?). An
already-loaded file can still be signaled by a nil return value, and a
file could pretend to be already loaded (if that's at all useful) by
choosing nil as its return value...

Food for thought :-)

--
Alex

Updated by rkh (Konstantin Haase) almost 13 years ago

One real use case I see would be avoiding global state (like CommonJS). However, if an already required file return nil, this is not possible.

Updated by mame (Yusuke Endoh) about 12 years ago

  • Status changed from Open to Assigned
  • Assignee set to matz (Yukihiro Matsumoto)

Updated by trans (Thomas Sawyer) about 12 years ago

I've had occasion to use this as well, especially for RUBY_VERSION specific code.

I wonder if it is okay to be embedded in other code though. Would this work?

  class Q
    def foo
      exit_script
    end
  end

  Q.new.foo

Is it a good idea for it to work? Or should exit_script only be allowed at toplevel?

Updated by mame (Yusuke Endoh) almost 12 years ago

Received. Thanks for quick action!

But, matz said "returning from outside of a method makes me so weird" once.
I'm ok if you want to give it a second try with no change, but I guess matz is not likely to accept it for the same reason.
(Well, but, maybe it isn't so bad way because he sometimes changes his mind)

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 12 years ago

thanks for worrying, but I'll take the risk :)

Updated by mame (Yusuke Endoh) over 11 years ago

Rodrigo Rosenfeld Rosas,

At the developer meeting (7/21), Matz was basically positive
to this proposal, but it turned out that we still need to
discuss corner cases.

Here is a discussion summary.

  • Matz said that he will accept "return from toplevel", but
    that reject "return from class definition".

    return if cond # OK
    class Foo
      return if cond # NG
    end
    
  • "return from toplevel" should always discard the argument.

  • What's happen if it returns from the start script (the given
    script to interpreter as a cmdline)?

    • The argument should be discarded; it does NOT affect the
      process termination status code

    • The same as "exit", but cannot rescue SystemExit

  • What's happen in the following corner cases?

    • eval("return") in toplevel

    • proc { return }.call in toplevel

  • Matz prefered "return" to "a special exception that require
    and load rescue",

    • though some people (including ko1) prefered the latter.

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 11 years ago

Em 23-07-2012 10:12, mame (Yusuke Endoh) escreveu:

Issue #4840 has been updated by mame (Yusuke Endoh).

Rodrigo Rosenfeld Rosas,

At the developer meeting (7/21), Matz was basically positive
to this proposal, but it turned out that we still need to
discuss corner cases.

Here is a discussion summary.

  • Matz said that he will accept "return from toplevel", but
    that reject "return from class definition".

    return if cond # OK
    class Foo
      return if cond # NG
    end
    

Totally agree.

  • "return from toplevel" should always discard the argument.

You mean "return something", right? I agree. Maybe we could even issue
an exception if anything other than just "return" is used.

  • What's happen if it returns from the start script (the given
    script to interpreter as a cmdline)?

    • The argument should be discarded; it does NOT affect the
      process termination status code

    • The same as "exit", but cannot rescue SystemExit

Agreed. Specifically "return" should be equivalent to "exit 0", right?
And "return -1" (or any other value, including 0) shouldn't be allowed
in my opinion, raising an exception, in which case the return value
wouldn't be 0 obviously :)

  • What's happen in the following corner cases?

    • eval("return") in toplevel

I'd vote for just abandoning any subsequent code in the eval and nothing
else. Maybe for that case "return" could use the arguments for the
result of "eval".

  • proc { return }.call in toplevel

If it is the main program, "exit" would be the equivalent. Otherwise, no
code would be interpreted after the "call" call.

I don't understand what makes this so special.

  • Matz prefered "return" to "a special exception that require
    and load rescue",

    • though some people (including ko1) prefered the latter.

I'm okay with raising an exception that would be rescued by require,
require_relative and load.

Actually I guess this is the simpler approach and it fulfills all the
real use cases I could think of in this moment.

Updated by alexeymuranov (Alexey Muranov) over 11 years ago

How about redefining __END__ to allow to call it as a method?

To avoid ambiguity with DATA constant, maybe __START_DATA__ keyword can be added?

Updated by ko1 (Koichi Sasada) over 11 years ago

(2012/07/24 0:44), alexeymuranov (Alexey Muranov) wrote:

How about redefining __END__ to allow to call it as a method?

It has compatibility issue that __END__ is related to DATA.

--
// SASADA Koichi at atdot dot net

Updated by ko1 (Koichi Sasada) over 11 years ago

(2012/07/23 23:57), Rodrigo Rosenfeld Rosas wrote:

  • "return from toplevel" should always discard the argument.

You mean "return something", right? I agree. Maybe we could even issue
an exception if anything other than just "return" is used.

  • What's happen if it returns from the start script (the given
    script to interpreter as a cmdline)?

    • The argument should be discarded; it does NOT affect the
      process termination status code

    • The same as "exit", but cannot rescue SystemExit

Agreed. Specifically "return" should be equivalent to "exit 0", right?
And "return -1" (or any other value, including 0) shouldn't be allowed
in my opinion, raising an exception, in which case the return value
wouldn't be 0 obviously :)

matz proposed that ignore return argument completely. matz also said to
avoid mistake, return expression with argument (example: "return foo")
should be syntax error.

  • proc { return }.call in toplevel

If it is the main program, "exit" would be the equivalent. Otherwise, no
code would be interpreted after the "call" call.

I don't understand what makes this so special.

(1)

pr = proc{return}
def foo(pr)
  pr.call # what happen?
end

(1')

1.times{
  return
}

(2)

# a.rb
$pr = proc{return}

# b.rb
require './a.rb'
$pr.call # waht happen?

(3)

begin
  ...
rescue
  return
ensure
  return
end

matz proposed that "accept return on toplevel (not in block, classes, etc)".

  • Matz prefered "return" to "a special exception that require
    and load rescue",

    • though some people (including ko1) prefered the latter.

I'm okay with raising an exception that would be rescued by require,
require_relative and load.

Actually I guess this is the simpler approach and it fulfills all the
real use cases I could think of in this moment.

I strongly recommended the exception approach because there are NO
difficult corner cases.

However, matz disagreed the exception approach because of "raise
StopLoading is too long". It is a kind of "name is not good".

--
// SASADA Koichi at atdot dot net

Updated by trans (Thomas Sawyer) over 11 years ago

How about redefining __END__ to allow to call it as a method?

It has compatibility issue that __END__ is related to DATA.

Then what about __end__?

Tangentially, why not deprecate __END__? Is there some really
important use case that we just can't live without? The whole idea
strikes me as rather hackish, especially considering it is limited to
main file.

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 11 years ago

Em 23-07-2012 22:37, SASADA Koichi escreveu:

(2012/07/23 23:57), Rodrigo Rosenfeld Rosas wrote:

  • "return from toplevel" should always discard the argument.
    You mean "return something", right? I agree. Maybe we could even issue
    an exception if anything other than just "return" is used.
  • What's happen if it returns from the start script (the given
    script to interpreter as a cmdline)?

    • The argument should be discarded; it does NOT affect the
      process termination status code

    • The same as "exit", but cannot rescue SystemExit
      Agreed. Specifically "return" should be equivalent to "exit 0", right?
      And "return -1" (or any other value, including 0) shouldn't be allowed
      in my opinion, raising an exception, in which case the return value
      wouldn't be 0 obviously :)
      matz proposed that ignore return argument completely. matz also said to
      avoid mistake, return expression with argument (example: "return foo")
      should be syntax error.

Better yet.

- proc { return }.call in toplevel

If it is the main program, "exit" would be the equivalent. Otherwise, no
code would be interpreted after the "call" call.

I don't understand what makes this so special.
(1)

pr = proc{return}
def foo(pr)
  pr.call # what happen?
end

I wonder why someone would write code like this in the first place, but
if someone did he is probably expecting the program to terminate with
exit if this is the main file. For required files I have no idea what
someone would expect from code like this. I'd probably raise an
exception in such situation because it is most likely a logic error that
could be hard to debug... I know what you mean, should that method "foo"
be defined or not? What should be its definition? I have no idea because
code like this simply doesn't make any sense to me.

(1')

1.times{
  return
}

This one I can think of. But something like:

['a', 'b'].each {|item|
   return if defined? item2module(item)
}

This would simply return from the require. I still don't understand why
this would be so special.

(2)

# a.rb
$pr = proc{return}

Wow! I wouldn't ever think in something like this! Congratulations,
you're really creative!

Again, why the hell would someone do something like this? I'd just raise
an error when trying to call $pr because return has no more meaning
after that file has been already required.

# b.rb
require './a.rb'
$pr.call # waht happen?

(3)

begin
  ...
rescue
  return
ensure
  return
end

matz proposed that "accept return on toplevel (not in block, classes, etc)".

I agree, this is way more simple to deal with. Even though I can think
about someone using an approach like above, he could also rewrite it like:

# ['a', 'b'].each {|item|
#  return if defined? item2module(item)
#}

return if ['a', 'b'].any?{|item|  defined? item2module(item) }
  • Matz prefered "return" to "a special exception that require
    and load rescue",

    • though some people (including ko1) prefered the latter.
      I'm okay with raising an exception that would be rescued by require,
      require_relative and load.

Actually I guess this is the simpler approach and it fulfills all the
real use cases I could think of in this moment.
I strongly recommended the exception approach because there are NO
difficult corner cases.

Agreed.

However, matz disagreed the exception approach because of "raise
StopLoading is too long". It is a kind of "name is not good".

So it would be just a matter of finding a better name, right? Not that I
think it should make any difference because ideally only Ruby internals
should see such errors in my opinion.

But if he thinks StopLoading is too long (while I find it short) it will
be hard to find a shorter meaningful name I guess.

Maybe after a good night of sleep, who knows...

Updated by shyouhei (Shyouhei Urabe) over 11 years ago

On 2012年07月24日 11:42, Trans wrote:

How about redefining __END__ to allow to call it as a method?

It has compatibility issue that __END__ is related to DATA.

Then what about __end__?

Tangentially, why not deprecate __END__? Is there some really
important use case that we just can't live without? The whole idea
strikes me as rather hackish, especially considering it is limited to
main file.

I'd be much appreciated if __END__ was usable from a library file.

I'd write a tiny loader script and place obfuscated script body on __END__ then.

Updated by drbrain (Eric Hodel) over 11 years ago

On Jul 23, 2012, at 7:42 PM, Trans wrote:

why not deprecate __END__? Is there some really
important use case that we just can't live without? The whole idea strikes me as rather hackish, especially considering it is limited to main file.

I infrequently use __END__ for single-file scripts. It's easier to transport a single file with embedded data than two or more files.

Updated by mame (Yusuke Endoh) over 11 years ago

  • Target version set to 2.0.0

Updated by mame (Yusuke Endoh) over 11 years ago

Anyone create a patch conformed to the spec written in [ruby-core:46648]?

I guess that my experimental patch ([ruby-core:36811]) is not confirmed completely;
perhaps it allows "return from class definition" (but I didn't tested yet).

--
Yusuke Endoh

Updated by yhara (Yutaka HARA) about 11 years ago

  • Status changed from Assigned to Feedback
  • Assignee changed from matz (Yukihiro Matsumoto) to mame (Yusuke Endoh)
  • Target version changed from 2.0.0 to 2.6

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 11 years ago

Pretty simple, indeed :) Not that I understand it, just that I appreciate its simplicity ;)

Updated by phluid61 (Matthew Kerwin) almost 11 years ago

On May 9, 2013 12:14 PM, "nobu (Nobuyoshi Nakada)"
wrote:

Issue #4840 has been updated by nobu (Nobuyoshi Nakada).

File 0001-compile.c-toplevel-return.patch added

A simple patch.

Line 369 has a typo in "rescue"

Updated by nobu (Nobuyoshi Nakada) almost 10 years ago

  • Description updated (diff)

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 10 years ago

Yusuke, would the patch proposed by Nobu with the typo fix for rescue be good enough?

Updated by mame (Yusuke Endoh) almost 10 years ago

  • Assignee changed from mame (Yusuke Endoh) to nobu (Nobuyoshi Nakada)

I trust nobu more than myself. Thank you!

--
Yusuke Endoh

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 8 years ago

Thanks for the update, but I'd like to point out the description in that document is not accurate:

### Before
unless cond
  class C
  end
end
# … or …
class C
end unless cond

This is like the actual code looks like (the one that motivated this feature request):

https://github.com/grjones/gitorious-submodule-dependencies/blob/master/config/initializers/gitorious_config.rb

unless defined? GitoriousConfig
  GitoriousConfig = c = YAML::load_file(File.join(Rails.root,"config/gitorious.yml"))[RAILS_ENV]

  # make the default be publicly open
  GitoriousConfig["public_mode"] = true if GitoriousConfig["public_mode"].nil?

  # ...

As you can see, the assumption that we would be dealing with a conditional single class declaration is false, so, the alternative proposal for currently handling this situation does not really apply in several cases.

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

Stalling due to unresolved bugs.

Current status: https://gist.github.com/nobu/e70b0c897b12b936e063

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 7 years ago

I'm not sure I understand that link. What is 1, 2, 3 and 4? What are the bugs?

Updated by shyouhei (Shyouhei Urabe) over 7 years ago

We looked at this issue at yesterday's developer meeting. No problem to introduce this feature was reported, except it is not implemented yet. Nobu tried this before and had technical difficulty; not sure if that could be rerouted. We are basically waiting for him (&others) to complete.

Actions #43

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

  • Status changed from Feedback to Closed

Applied in changeset r57132.


compile.c: toplevel return

  • compile.c (iseq_compile_each): stop execution of the current source
    by toplevel return. [ruby-core:36785] [Feature #4840]
Actions #44

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Related to Bug #13678: toplevel return causes [BUG] added
Actions #45

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Related to Bug #13682: return inside of ensure causes [BUG] added
Actions #46

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Related to Bug #13755: Null pointer dereference in hash_table_index() added

Updated by headius (Charles Nutter) over 6 years ago

Were any tests or specs added for this feature? I don't see anything recent added to language/return_spec.rb and the related commits don't show any additions to MRI's tests.

I believe we need at least one of these to be filled out. I'd be happy to do it but this is a very long thread and I'm not sure what is or is not considered spec.

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

test/ruby/test_syntax.rb:test_return_toplevel

Updated by headius (Charles Nutter) over 6 years ago

Ahh great, thank you for the pointer, nobu!

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) over 6 years ago

Could someone please explain me what is the current status of this feature? I thought I would be able to return from the top-level when requiring a file, but it still seems to be an invalid syntax to this day. Am I missing something?

Actions #51

Updated by mame (Yusuke Endoh) over 6 years ago

It works for me. How did you test?

$ cat t.rb
p 1
return
p 2
$ ruby -v t.rb
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
t.rb:3: warning: statement not reached
1
$ /tmp/local/bin/ruby -v t.rb
ruby 2.5.0rc1 (2017-12-14 trunk 61243) [x86_64-linux]
t.rb:3: warning: statement not reached
1
Actions #52

Updated by matz (Yukihiro Matsumoto) about 6 years ago

  • Related to Bug #14062: Top-level return allows an argument added
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0