Generalized break?

H

Hal Fulton

I hate to bring up possible language changes, since there is
so much of that going around.

Matz, if this is stupid, just tell me so.

I've sometimes wished for a "break" that would work in (almost) any
context -- one that would do "the sensible thing" instead of just
giving an error saying you can't do a break here.

Two examples are:

1. A long string, possibly multiline/multi-statement, is being
evaled. I want the capability to abort the eval.

2. I have a mild dislike for the idiom if $0 == __FILE__ (lines) end
-- because I always indent inside an if, and I don't want to indent,
and I really just want to say: break if $0 != __FILE__


In both these contexts, I initially tried exit. Of course, that
doesn't work -- it exits the entire program. A "return" seems like
the next choice, but that only makes sense within a method.

There's no proper way to do this kind of thing, as far as I can
see.

Thoughts?

Hal
 
W

Wesley J Landaker

--Boundary-02=_If7z/zAyb7lYFir
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Description: signed data
Content-Disposition: inline

I've sometimes wished for a "break" that would work in (almost) any
context -- one that would do "the sensible thing" instead of just
giving an error saying you can't do a break here.

Two examples are:

1. A long string, possibly multiline/multi-statement, is being
evaled. I want the capability to abort the eval.

2. I have a mild dislike for the idiom if $0 =3D=3D __FILE__ (lines) end
-- because I always indent inside an if, and I don't want to indent,
and I really just want to say: break if $0 !=3D __FILE__

I actually would like that too, especially for #2, since it avoids lots=20
of nasty nesting for unit tests and such.
In both these contexts, I initially tried exit. Of course, that
doesn't work -- it exits the entire program. A "return" seems like
the next choice, but that only makes sense within a method.

I think break makes sense here, and I'd use it if it were available.
There's no proper way to do this kind of thing, as far as I can
see.

Well, maybe not proper, but here is *a* way to do it. ;)

#!/usr/bin/ruby

puts "File loaded."

if $0 =3D=3D __FILE__ then puts <<-EOF ; end

# look, no indent, and we're not nested in an if! =3D)
puts "File called directly."

EOF



=2D-=20
Wesley J. Landaker - (e-mail address removed)
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2


--Boundary-02=_If7z/zAyb7lYFir
Content-Type: application/pgp-signature
Content-Description: signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQA/z7fH8KmKTEzW49IRAiw7AJkB1uBHqAQdHPfeePGZcE5/FvyjigCcDLv3
SOkwsuP4LccDfRZrDlhi5b8=
=25q1
-----END PGP SIGNATURE-----

--Boundary-02=_If7z/zAyb7lYFir--
 
G

Gennady

Hal said:
I hate to bring up possible language changes, since there is
so much of that going around.

Matz, if this is stupid, just tell me so.

I've sometimes wished for a "break" that would work in (almost) any
context -- one that would do "the sensible thing" instead of just
giving an error saying you can't do a break here.

Two examples are:

1. A long string, possibly multiline/multi-statement, is being
evaled. I want the capability to abort the eval.

2. I have a mild dislike for the idiom if $0 == __FILE__ (lines) end
-- because I always indent inside an if, and I don't want to indent,
and I really just want to say: break if $0 != __FILE__


In both these contexts, I initially tried exit. Of course, that
doesn't work -- it exits the entire program. A "return" seems like
the next choice, but that only makes sense within a method.

There's no proper way to do this kind of thing, as far as I can
see.

If you just do not want to indent, I would suggest

if $0 == __FILE__
eval DATA.readlines.join("\n"), binding, __FILE__
end
__END__
puts "HELLO"

It looks ugly and excessive, I agree. It also has problems with error
reporting, whatever line number it shows you have to add 4 (in this
particular case) to it mentally.

It works, however ;-)

Gennady.
 
W

Wesley J Landaker

--Boundary-02=_An7z/JO8rOLNyoX
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Description: signed data
Content-Disposition: inline

Well, maybe not proper, but here is *a* way to do it. ;)

#!/usr/bin/ruby

puts "File loaded."

if $0 =3D=3D __FILE__ then puts <<-EOF ; end

# look, no indent, and we're not nested in an if! =3D)
puts "File called directly."

EOF

Err, that just prints things out, nevermind. (I wasn't serious anyway ;)

=2D-=20
Wesley J. Landaker - (e-mail address removed)
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2


--Boundary-02=_An7z/JO8rOLNyoX
Content-Type: application/pgp-signature
Content-Description: signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQA/z7nA8KmKTEzW49IRAigMAJ4sU84Oo8VMIQC0l9SR8IQ1FgARlQCeJqn9
RF5EgP5n7X4yaAnkCYDoLtA=
=dP18
-----END PGP SIGNATURE-----

--Boundary-02=_An7z/JO8rOLNyoX--
 
A

Ara.T.Howard

Date: Fri, 5 Dec 2003 07:13:04 +0900
From: Hal Fulton <[email protected]>
Newsgroups: comp.lang.ruby
Subject: Generalized break?

I hate to bring up possible language changes, since there is
so much of that going around.

Matz, if this is stupid, just tell me so.

I've sometimes wished for a "break" that would work in (almost) any
context -- one that would do "the sensible thing" instead of just
giving an error saying you can't do a break here.

Two examples are:

1. A long string, possibly multiline/multi-statement, is being
evaled. I want the capability to abort the eval.

catch/throw is pretty general:

this works:

code = <<-code
if true
def method
42
end
if not false
if true
loop do
p method
throw :bail if rand < 0.5
end
end
end
end
code


def nesting code
eval code
end

catch :bail do
nesting code
end

2. I have a mild dislike for the idiom if $0 == __FILE__ (lines) end
-- because I always indent inside an if, and I don't want to indent,
and I really just want to say: break if $0 != __FILE__

agreed.

how about something like

__TEST__

for this?
In both these contexts, I initially tried exit. Of course, that
doesn't work -- it exits the entire program. A "return" seems like
the next choice, but that only makes sense within a method.

There's no proper way to do this kind of thing, as far as I can
see.

Thoughts?

Hal

-a

--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
J

Joel VanderWerf

Hal said:
2. I have a mild dislike for the idiom if $0 == __FILE__ (lines) end
-- because I always indent inside an if, and I don't want to indent,
and I really just want to say: break if $0 != __FILE__

This seems to work:

=== x.rb ===
puts "loading x.rb"

alias old_load load
def load(*args)
catch :break_from_load do
old_load(*args)
end
end

throw :break_from_load unless __FILE__ == $0

puts "a"

load(__FILE__)

puts "b"
============
 
G

Gennady

Joel said:
This seems to work:

=== x.rb ===
puts "loading x.rb"

alias old_load load
def load(*args)
catch :break_from_load do
old_load(*args)
end
end

throw :break_from_load unless __FILE__ == $0

puts "a"

load(__FILE__)

puts "b"
============

You get the following error when you 'require' this file:

irb(main):001:0> require 'x'
loading x.rb
NameError: uncaught throw `break_from_load'
from ./x.rb:11:in `throw'
from ./x.rb:11
from (irb):1:in `require'
from (irb):1
irb(main):002:0>


Gennady.
 
W

Wesley J Landaker

--Boundary-02=_O19z/3OO9Vr/u5/
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Description: signed data
Content-Disposition: inline

agreed.

how about something like

__TEST__

for this?

Ooohh, I like that! =3D)

(Hmmm... can we implement it in ruby as is? ... using the eval hack=20
posted earlier in this thread sort of works, although this is a bit=20
ugly):

=2D-- test.rb ---
#!/usr/bin/ruby

def __TEST__(file)
if $0 =3D=3D file
eval DATA.readlines.join("\n"), binding, file
end
end


=2D-- demo.rb ---
#!/usr/bin/ruby

#!/usr/bin/ruby
require 'test'

puts "1"

__TEST__(__FILE__)
__END__

puts "2"


Then:
$ ./demo.rb
1
2
$ irb
irb(main):001:0> require 'demo'
1
=3D> true

Not sure how to get around passing __FILE__ in, or having __END__ there=20
as well...

=2D-=20
Wesley J. Landaker - (e-mail address removed)
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2


--Boundary-02=_O19z/3OO9Vr/u5/
Content-Type: application/pgp-signature
Content-Description: signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQA/z91O8KmKTEzW49IRApUqAJ9nvSwfKj94tFT5zawIGfLPgtpgjgCfTv3C
ZDvXhW4m2+F1tqC597XZi0w=
=Ck+9
-----END PGP SIGNATURE-----

--Boundary-02=_O19z/3OO9Vr/u5/--
 
A

Ara.T.Howard

Ooohh, I like that! =3D)

;-) me too.
Not sure how to get around passing __FILE__ in, or having __END__ there=20
as well...

well, for __FILE__ you could

def __TEST__ (file = __FILE__)
...
end

couldn't you?

-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
Y

Yukihiro Matsumoto

Hi,

In message "Generalized break?"

|I've sometimes wished for a "break" that would work in (almost) any
|context -- one that would do "the sensible thing" instead of just
|giving an error saying you can't do a break here.

"break" or jump in general requires destination. If you want
something like "generalized break", you have to define the destination
for each context. Basically, catch/throw is prepared for that
purpose.

|1. A long string, possibly multiline/multi-statement, is being
|evaled. I want the capability to abort the eval.

Use catch/throw.

|2. I have a mild dislike for the idiom if $0 == __FILE__ (lines) end
|-- because I always indent inside an if, and I don't want to indent,
|and I really just want to say: break if $0 != __FILE__

I think it's not a good idea that preparing single syntax construct to
serve too many purpose. I admit "$0 != __FILE__" hack is ugly, but it
should be solved by some other way than "generalized break.

matz.
 
W

Wesley J Landaker

--Boundary-02=_m//z/RAP37FJasM
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Description: signed data
Content-Disposition: inline

;-) me too.


well, for __FILE__ you could

def __TEST__ (file =3D __FILE__)
...
end

couldn't you?

That doesn't work in this case, because then __FILE__ refers to=20
"test.rb" instead of "demo.rb". There is probably a way to get around=20
that, but I haven't tried real hard.=20

=2D-=20
Wesley J. Landaker - (e-mail address removed)
OpenPGP FP: 4135 2A3B 4726 ACC5 9094 0097 F0A9 8A4C 4CD6 E3D2


--Boundary-02=_m//z/RAP37FJasM
Content-Type: application/pgp-signature
Content-Description: signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQA/z//m8KmKTEzW49IRAstmAJ0bY9mNtxHrSK51SypFDsekGaobkwCaApmu
W7xmrHBADJWjsy9bf76nAtQ=
=V5fk
-----END PGP SIGNATURE-----

--Boundary-02=_m//z/RAP37FJasM--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,815
Members
47,361
Latest member
RogerDuabe

Latest Threads

Top