Another random idea -- "break" at toplevel

There have been times that I wanted to just skip to the bottom of
the current file.

For one example, consider this idiom (not as popular as it used
to be):

if $0 == __FILE__
   # Possibly many lines
end

I’d like to write this as:

break if $0 != __FILE__

But of course, that doesn’t work. And of course, exit would be
appropriate if your program itself is in the current file.

Has anyone else ever thought along these lines? I grant that the
usefulness is very limited.

A part of me thought: Well, should “break” just jump to the bottom
of the innermost enclosing context? And a part of me likes this, but
a part feels there are excellent reasons not to do it.

For example: If you’re inside a method but not inside a loop, break
would act the same as return. It might confuse you if you think your
break is inside a loop but isn’t – it would return instead of giving an
error. (But if you can’t tell the inside of a loop from the outside,
your
code needs to be made prettier.)

Break inside a block, of course, is like a “return” from/for the block.
That, I suppose, is the only time break takes a value – but I don’t
think it would break anything (inside a method) if it always took a
value.

In that case, loops and class definitions could have (meaningful)
return values.

The only time I envision this "break " being truly useless is
breaking from inside a required file – we don’t want to harm the
semantics of require() returning true/false, and I can’t think where
else the value would go.

Unless we made “break” at toplevel of a require return true by default

but that seems even uglier.

On a side note, the “$0 == FILE” expression is ugly to me. What
I really would like if something like:

break if __REQUIRED__

or simply

__MAIN__

But this is just me rambling. Comment or ignore as you wish.

Cheers,
Hal

Hal F. писал 03.07.2012 00:39:

I’d like to write this as:

break if $0 != __FILE__

But of course, that doesn’t work. And of course, exit would be
appropriate if your program itself is in the current file.

Has anyone else ever thought along these lines? I grant that the
usefulness is very limited.

Well, this is pretty easy to implement and, I admit, somewhat logical.
Could you post your feature request at http://redmine.ruby-lang.org/ ?
If it will be ‘approved’ by someone from Ruby Core team I’d just go
and implement that for MRI.

your
code needs to be made prettier.)

I’m not sure if I like this or not. On one hand, break already has
double
semantics (block and loop context). On the other one, I never quite
liked
this feature, as it’s somewhat confusing.

Break inside a block, of course, is like a “return” from/for the
block.
That, I suppose, is the only time break takes a value – but I don’t
think it would break anything (inside a method) if it always took a
value.

In that case, loops and class definitions could have (meaningful)
return values.

Break from a loop makes the loop return a value, too.

i = 0; while i < 5; i += 1; end

=> nil

i = 0; while i < 5; i += 1; break 1; end

=> 1

And class definitions very certainly can return a meaningful value.
Here
is a real-world example: getting a singleton class syntactically.

o = Object.new; p class << o; self; end

=> #<Class:#Object:0x000000025b47b0>

The only time I envision this “break ” being truly useless is
breaking from inside a required file – we don’t want to harm the
semantics of require() returning true/false, and I can’t think where
else the value would go.

Unless we made “break” at toplevel of a require return true by
default –
but that seems even uglier.

Return value of require' has nothing to do with the contents of the loaded file, and we definitely should keep it that way. (Note that I'm not saying it is anyhow useful. IMHO require’ could just return nil as well, and
in
those very rare cases when you actually need to know if a feature was
loaded
previously you could just check $LOAD_PATH.)

On a side note, the “$0 == FILE” expression is ugly to me. What
I really would like if something like:

break if __REQUIRED__

Note that require' is not the only true way to load files in Ruby. You also have load’, `eval’ and so on, so the name REQUIRED would be
misleading.
Also, making it a keyword will break those (probably very rare) cases
where
it’s been used as a variable name. (I’ve been bitten by someone from
TC-39
committee.)

or simply

__MAIN__

This is, again, confusing and incompatible. Not only this will require
adding
new keywords for doubtful reasons, it’s also not clear what this code
does.
`if $0 == FILE’ will be understood by anyone familiar with Unix
(“familiar
with Unix” implies that you’re familiar with Bash and C); at least
FILE
can be easily googled, it’s present in keyword list and it has broader
usage
than just that statement alone. What you’re trying to add is, actually,
a
completely new control flow construct for just one corner case.

(Also, using $0 as argv[0] and $[1…262144] for regexp unnamed captures
was
an utterly moronic decision. Only several things are worse, like
Perl-style
global variables. Do you remember what $/ does and which functions are
affected by $= ?)

On Mon, Jul 2, 2012 at 10:39 PM, Hal F. [email protected]
wrote:

There have been times that I wanted to just skip to the bottom of
the current file.

It is not entirely clear to me what “bottom” actually means. For
example, what happens to END blocks?

Kind regards

robert

Uhm… Perhaps this will help you:

module Kernel
def require_skip(*args)
catch(:skip) do
$SKIPPABLE_REQUIRE = true
require *args
$SKIPPABLE_REQUIRE = false
end
end
end

and then, do something like:

Requester

require_skip ‘requestd.rb’

requested.rb

throw :skip if $SKIPPABLE_REQUIRE

If you always want use require_skip instead of require, use this one:
module Kernel
alias :old_require :require
def require(*args)
catch(:skip) do
$REQUIRED = true
old_require *args
$REQUIRED = false
end
end
end

If you want do something like this piece of python:
if FILE == ‘main’:
main()

There’s the Ruby equivalent:
if self.to_s == ‘main’
main()