Forum: Ruby goto function?

Posted by fabsy (Guest)
on 2006-08-15 21:30
(Received via mailing list)
Hey!
I have been trying to find a goto function in ruby..
Like this:

foo: bar
If blabla then GOTO foo

Is there any command for exiting the app?
And how do I search ex a textfile for a certain word and delete it?


------

if value == "2"
		system('clear')
		print "[Opening file..]\n\n"
			r_file = File.open( "file", "a") #Wrote this so I wouldn't get an
error like "File doesn't exist".
			r_file = File.open( "file", "r")
			print "-----\n"
			print r_file.read
			print "-----"
			print "\n"
			system ('ruby note.rb')  #is there anyway to restart or goto the
beginning of the script?
		end

-----

Thanks!
Posted by darren kirby (Guest)
on 2006-08-15 22:30
(Received via mailing list)
quoth the fabsy:
> Hey!
> I have been trying to find a goto function in ruby..
> Like this:
>
> foo: bar
> If blabla then GOTO foo

Use a function:

def foo
  #whatever foo does

foo() if blabla

or invert the test:

foo() unless !blabla

> Is there any command for exiting the app?

Yeah: 'exit'

> And how do I search ex a textfile for a certain word and delete it?

Probably lots of ways. One would be to read the file to a string and use
gsub(). See the String and IO docs
http://www.whytheluckystiff.net/ruby/pickaxe/html/...

> 			print "-----"
> 			print "\n"
> 			system ('ruby note.rb')  #is there anyway to restart or goto the
> beginning of the script?
> 		end
>
> -----
>
> Thanks!

-d
Posted by Robert Klemme (Guest)
on 2006-08-15 22:57
(Received via mailing list)
fabsy wrote:
> 
> 			print "-----"
> 			print "\n"
> 			system ('ruby note.rb')  #is there anyway to restart or goto the
> beginning of the script?
> 		end
> 
> -----
> 
> Thanks!
> 

begin
...
end while your_condition_here

begin
...
end until your_condition_here

If you need an endless loop

loop do
...
end

See also
http://ruby-doc.org/docs/ProgrammingRuby/html/tut_...

Note that your script opens the file over and over again and never
closes it.  This can cause problems - especially since you do it with
different modes.

Kind regards

	robert
Posted by fabsy (Guest)
on 2006-08-15 23:06
(Received via mailing list)
> loop do
> Kind regards
>
> 	robert

I don't really understand..

I want the script to start over again.. for example..
When the user made an input and pressed return I want the script to
"restart" or jump to the beginning..
Posted by Logan Capaldo (Guest)
on 2006-08-15 23:30
(Received via mailing list)
On Aug 15, 2006, at 5:05 PM, fabsy wrote:

>> If you need an endless loop
>> different modes.
>>
>> Kind regards
>>
>> 	robert
>
> I don't really understand..
>
> I want the script to start over again.. for example..
> When the user made an input and pressed return I want the script to
> "restart" or jump to the beginning..


I wouldn't recommend making this a habit but:

% cat cc.rb
x = 0
bar = callcc {|cc| cc}
puts "Hello"
x += 1
bar.call(bar) unless x == 3
puts "x is #{x}"

% ruby cc.rb
Hello
Hello
Hello
x is 3
Posted by unknown (Guest)
on 2006-08-15 23:51
(Received via mailing list)
On Aug 15, 2006, at 5:28 PM, Logan Capaldo wrote:
> I wouldn't recommend making this a habit but:
>
> % cat cc.rb
> x = 0
> bar = callcc {|cc| cc}
> puts "Hello"
> x += 1
> bar.call(bar) unless x == 3
> puts "x is #{x}"

Yikes, someone asks questions which indicate that they
are a novice programmer and you throw continuations at them?

Isn't that like throwing someone in the deep end of the pool and
seeing if they can swim? Or maybe it is like holding them under
water and seeing if they have gills? :-)

Fasby wrote:
> I don't really understand..
>
> I want the script to start over again.. for example..
> When the user made an input and pressed return I want the script to
> "restart" or jump to the beginning..

You can use 'next' to begin the next iteration of a loop:

loop {
   # your code here
   if startover?
      next		# will cause loop to start over
   end
   # more stuff here
   if quit?
     break		# to get out of the loop entirely
   end
   # more stuff here
}


Gary Wright
Posted by David Vallner (Guest)
on 2006-08-15 23:54
(Received via mailing list)
On Tue, 15 Aug 2006 23:05:10 +0200, fabsy <fabbyfabs@gmail.com> wrote:
> I want the script to start over again.. for example..
> When the user made an input and pressed return I want the script to
> "restart" or jump to the beginning..
>

Let me introduce you to my good friend: structured programming. I'm sure
you'll get along marvelous once you get to know each other.

The BASIC construct of "goto" is rightfully considered harmful for
programs above a certain complexity. It's not present in Ruby in any
direct way that would let you jump around a program's structure
arbitrarily. (Actually, that's a lie, but I'll hold the continuations 
for
the sake of simplicity.)

If you want a script to start over, the easiest way is to put all the
logic of the script into a function / procedure / whatever, and 
repeatedly
call that one in a loop like Darren and Robert indicated.

If you want the script to react to user input, you could for example do:

def do_stuff_with_file(r_file)
	# Most of your original code goes here.
end

should_print_file = true
while should_print_file

	# Better way to avoid file not found errors - you're creating a 
completely
	# useless temporary file as a workaround.
	File.open('file') { | r_file | do_stuff_with_file(r_file) } if
File.exist? ('file')

	puts('Print file again? [y/n]')
	should_print_file = (gets[0] == 'y') # Flaky bit, should be more
forgiving.

end

David Vallner
Posted by Timothy Goddard (Guest)
on 2006-08-16 00:10
(Received via mailing list)
fabsy wrote:
>
> 			print "-----"
> 			print "\n"
> 			system ('ruby note.rb')  #is there anyway to restart or goto the
> beginning of the script?
> 		end
>
> -----
>
> Thanks!

There is a reason why there are no gotos in Ruby or the vast majority
of modern languages. They are the complete antithesis of good program
design. You should be writing something more like this:

while value == 2
  begin
    system("clear") # This is a pretty bad idea - it's not portable and
completely unneccesary.
    puts "[Opening file...]"
    puts
    File.open("file", "r") do |file|
      puts "---"
      puts file.read
      puts "---"
    end
    system("ruby note.rb") # What is this for?
  rescue Errno:ENOENT
    puts "File does not exist."
  end
end

This program properly handles file closing and uses exception handling
to pick up problems with opening the file. Exceptions and simple loops
can produce the same result as any GOTO mess while maintaining good
structure. I would avoid system() as well, but you may have your
reasons for using it.
Posted by Nathan Smith (Guest)
on 2006-08-16 00:13
(Received via mailing list)
On Wed, 16 Aug 2006, David Vallner wrote:

> programs above a certain complexity. It's not present in Ruby in any
> direct way that would let you jump around a program's structure
> arbitrarily. (Actually, that's a lie, but I'll hold the continuations for
> the sake of simplicity.)

<snip>

Obligatory response:

In some very rare circumstances, using gotos does in fact have a 
rightful
place in code. In very long switch/case statements in C code, a _very_
well structured (and properly named) set of labels/gotos can make code
much cleaner, and easier to understand, than if they were not used. But
I'll say again, this is very rare.

Nate
Posted by fabsy (Guest)
on 2006-08-16 00:16
(Received via mailing list)
Timothy Goddard skrev:

> >
> > 			print r_file.read
> There is a reason why there are no gotos in Ruby or the vast majority
>       puts "---"
> to pick up problems with opening the file. Exceptions and simple loops
> can produce the same result as any GOTO mess while maintaining good
> structure. I would avoid system() as well, but you may have your
> reasons for using it.

Naa, Im just testing to create something simple.. I think thats the
best way of learning..
So the system() thingy is just for test. :)
the  system("ruby note.rb") was just a solution to get the script to
"restart", I know it's a bad way but I had to try it. The system(clear)
was just so the screen was cleared.
Posted by Gennady Bystritsky (Guest)
on 2006-08-16 00:25
(Received via mailing list)
> > > I want the script to start over again.. for example..
> > programs above a certain complexity. It's not present in Ruby in any
> have a rightful
> place in code. In very long switch/case statements in C code, a _very_
> well structured (and properly named) set of labels/gotos can make code
> much cleaner, and easier to understand, than if they were not 
> used. But
> I'll say again, this is very rare.

I have to respectfully disagree. Having actively used C (among many
others) since 1986 up until now for professional development, I NEVER
found a good use for it, even in my early days. Especially in
switch/case statements ;-). It may be _very_ well structured in the
beginning, becoming a total mess with time. Never had very long
switch/case statements even on very big projects either. This is where
lookup tables with function pointers come in handy, for one.

Gennady.
Posted by Eero Saynatkari (roo)
on 2006-08-16 04:07
fabsy wrote:
> Hey!
> I have been trying to find a goto function in ruby..
> Like this:
> 
> foo: bar
> If blabla then GOTO foo
> 
> Is there any command for exiting the app?
> And how do I search ex a textfile for a certain word and delete it?
> 
> <snip for rforum />

Since no-one mentioned it, how about a throw/catch solution?

> Thanks!
Posted by David Vallner (Guest)
on 2006-08-16 04:25
(Received via mailing list)
On Wed, 16 Aug 2006 04:07:26 +0200, Eero Saynatkari
<eero.saynatkari@kolumbus.fi> wrote:
> Since no-one mentioned it, how about a throw/catch solution?

Throw / catch is for hairier nonlocal returns, he wanted to repeat
something using goto. Looping with a break or an end condition is easier
to understand (YMMV) if you don't need to get a result value of any 
sort.
But yes, that would also work. Especially since you can implement any
control construct with ruby's throw / catch if you're stark raving mad
enough.

David Vallner
Posted by Jeremy Tregunna (Guest)
on 2006-08-16 05:25
(Received via mailing list)
On 06-08-15, at 22:23, David Vallner wrote:

> On Wed, 16 Aug 2006 04:07:26 +0200, Eero Saynatkari  
> <eero.saynatkari@kolumbus.fi> wrote:
>> Since no-one mentioned it, how about a throw/catch solution?
>
> Throw / catch is for hairier nonlocal returns, he wanted to repeat  
> something using goto. Looping with a break or an end condition is  
> easier to understand (YMMV) if you don't need to get a result value  
> of any sort. But yes, that would also work. Especially since you  
> can implement any control construct with ruby's throw / catch if  
> you're stark raving mad enough.

Even if you need a return value you can break with a value. I.e.,

i = 0
loop do
   i = i + 1
   break i * i if i == 5
end

will return 25.

> David Vallner

--
Jeremy Tregunna
jtregunna@blurgle.ca


"One serious obstacle to the adoption of good programming languages
is the notion that everything has to be sacrificed for speed. In
computer languages as in life, speed kills." -- Mike Vanier
Posted by Logan Capaldo (Guest)
on 2006-08-16 05:55
(Received via mailing list)
On Aug 15, 2006, at 10:07 PM, Eero Saynatkari wrote:

>>
>> <snip for rforum />
>
> Since no-one mentioned it, how about a throw/catch solution?
>
I originally tried to do it with throw/catch, but its not really
"goto-y" enough. Hence the continuation solution.
Posted by Robert Klemme (Guest)
on 2006-08-16 11:07
(Received via mailing list)
On 15.08.2006 23:00, fabsy wrote:
>>
> I don't really understand..
You call File.open() but you do not call #close().  Note that there are
other means to read from a file, e.g you can do File.readlines or
File.read.  See RDOC here http://www.ruby-doc.org/core/

> I want the script to start over again.. for example..
> When the user made an input and pressed return I want the script to
> "restart" or jump to the beginning..

That's why I gave you the looping constructs.

	robert
Posted by fabsy (Guest)
on 2006-08-16 12:07
(Received via mailing list)
Yes, I fixed the file.close thing. :)
It was something I missed, the main problem I had was to get the script
to "start over".
Thanks everybody..
Posted by Christian Neukirchen (Guest)
on 2006-08-16 13:56
(Received via mailing list)
"David Vallner" <david@vallner.net> writes:

> The BASIC construct of "goto" is rightfully considered harmful for
> programs above a certain complexity. It's not present in Ruby in any
> direct way that would let you jump around a program's structure
> arbitrarily. (Actually, that's a lie, but I'll hold the continuations
> for  the sake of simplicity.)

It is often said that continuations are as powerful as goto.
But is there a way to jump *forward* with continuations, without
rewriting the code to use additional methods?
Posted by Simen Edvardsen (Guest)
on 2006-08-16 16:05
(Received via mailing list)
On 8/16/06, Christian Neukirchen <chneukirchen@gmail.com> wrote:
> rewriting the code to use additional methods?
>
> > David Vallner
> --
> Christian Neukirchen  <chneukirchen@gmail.com>  http://chneukirchen.org
>
>

A continuation is, by definition, the *continuation* of the
computation. But that probably wasn't the answer you wanted. There's
no way to do:

goto :a
label :a

Even though it's easy to create label and goto methods that work like 
this:

label :a
puts "after a"
goto :a if rand(2) % 2 == 0
Posted by Logan Capaldo (Guest)
on 2006-08-16 17:08
(Received via mailing list)
On Aug 16, 2006, at 7:55 AM, Christian Neukirchen wrote:

> rewriting the code to use additional methods?
>

Jumping forward:

callcc do |cc|
   puts "Some code"
   puts "Some more code"
   cc.call # jump forward
   puts "I'm never executed"
end
puts "Whee!"
Posted by David Vallner (Guest)
on 2006-08-16 21:24
(Received via mailing list)
On Wed, 16 Aug 2006 13:55:01 +0200, Christian Neukirchen
<chneukirchen@gmail.com> wrote:
> It is often said that continuations are as powerful as goto.
> But is there a way to jump *forward* with continuations, without
> rewriting the code to use additional methods?

As others said, continuations continue. You can jump backwards, because
you know the whole context to jump into - it already existed.

To jump forward in code without explicitly setting up a context in which
to run would either result in undefined behaviour, accepting some 
defaults
for the context (all local / instance / other nonglobal variables are 
nil,
for example), or the timespace continuum breaking. That might not apply 
if
you were scripting a time machine, of course.

This is precisely why goto is considered harmful in the first place - to
jump forward, you have to use only global context, or some other context
that is defined to be shared when using such a construct. It would be
interesting however if there was a concept of capture a (possible) 
future
point of code execution without having to do explicit setup via a 
command
object or something similar. I'll admit at this point that my savvy gets 
a
little fuzzy around very high level programming theory - so I might
actually be honking wrong in which case I'm all ears intrigued as to the
workings of that construct.

David Vallner
Posted by Pit Capitain (Guest)
on 2006-08-16 22:24
(Received via mailing list)
Simen Edvardsen schrieb:
> There's no way to do:
> 
> goto :a
> label :a

Right, but with some evil Ruby code, this is possible:

   irb(main):001:0> require "goto"
   => true
   irb(main):002:0> with_goto do
   irb(main):003:1*
   irb(main):004:1*   puts 1
   irb(main):005:1>   goto :b
   irb(main):006:1>
   irb(main):007:1* label :a
   irb(main):008:1>   puts 3
   irb(main):009:1>   goto :c
   irb(main):010:1>
   irb(main):011:1* label :b
   irb(main):012:1>   puts 2
   irb(main):013:1>   goto :a
   irb(main):014:1>
   irb(main):015:1* label :c
   irb(main):016:1>   puts 4
   irb(main):017:1>
   irb(main):018:1* end
   1
   2
   3
   4
   => nil
   irb(main):019:0>

No, I won't show the implementation yet. See
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/...

Regards,
Pit
Posted by Steve Martin (wrecklass)
on 2006-08-24 19:08
(Received via mailing list)
Ah very clever. Corrupting the minds of the innocent by introducing
bad programming practices to the language.

This reminds me of a conversation I had with one of my junior
programmers on a project back in the 80's. He argued that since the C
language specification included the GOTO statement it was perfectly
fine to use it. I pointed out that my Jeep had a roll bar, but that
didn't mean I should use it!
Posted by Frédéric Lemire (fredofromstart)
on 2012-10-09 23:45
My friends ! Let's not become dogmatic, please !!! …

I have nothing against standards in coding and all, but please, let us 
people write dirty code sometimes ! It can be so handy !

I like well indented code, and pushing a whole lot of code I want to 
make optional one indentation further is a pain in the back. There are 
many ways to program well, and there is also idiosyncratic or 
exceptional programming that may be way clearer with a blatant GOTO.

Why not ? I like it when a language gives me tools, handy tools, logical 
ones, for particular situations, like, imagine, you just want to have 
the data in a proper format and start doing nifty stuff with it right 
away. Who cares if the data-load part is not yet modularized, and all, 
and if there are some orange cones around your hefty chunk of code with 
multiple passes and all — with DEVIATION signs flashing in front it ? 
It's surely temporary, so, let's relaaax.

And… what if it wasn't temporary ? I agree that using it too much 
(especially backwards) is a bad habit, but in some situations, why not ? 
Like, we have a break instruction that is very handy to short-circuit 
the code and jump above it.

I like cleanliness and modularization, but I also like to have the eval 
command, and metaprogramming stuff to explore sometimes unexpected ways. 
So, why not a goto command ?

It's neat to be able to get dirty when one needs it and feels confident 
about it !

Anyway… for now, I'll just make exceptions to my indentation fixation, 
waiting for a freer future.

Ciao !
Posted by Eric Christopherson (echristopherson)
on 2012-10-10 00:15
(Received via mailing list)
On Tue, Oct 9, 2012 at 4:45 PM, Frédéric Lemire <lists@ruby-forum.com> 
wrote:
...
> I like cleanliness and modularization, but I also like to have the eval
> command, and metaprogramming stuff to explore sometimes unexpected ways.
> So, why not a goto command ?
>
> It's neat to be able to get dirty when one needs it and feels confident
> about it !
>
> Anyway… for now, I'll just make exceptions to my indentation fixation,
> waiting for a freer future.

You can use continuations (although I think I recall hearing that they
were either removed or dumbed down in 1.9).
Posted by Bartosz Dziewoński (matmarex)
on 2012-10-10 00:19
(Received via mailing list)
You can compile Ruby with SUPPORT_JOKE to enable goto.

http://patshaughnessy.net/2012/2/29/the-joke-is-on...

-- Matma Rex
Posted by Brandon Weaver (Guest)
on 2012-10-10 00:32
(Received via mailing list)
It's a question of structure and proper planning more than any type of
dogmatic fanboyism. Goto is not good practice. We have loops and 
recursion
for such things, and if you admit it's dirty then why in the world are 
you
using it? This is more of an appeal to logic and sanity than anything.
Posted by Peter Zotov (Guest)
on 2012-10-10 12:05
(Received via mailing list)
Eric Christopherson писал 10.10.2012 02:12:
>> confident
>> about it !
>>
>> Anyway… for now, I'll just make exceptions to my indentation
>> fixation,
>> waiting for a freer future.
>
> You can use continuations (although I think I recall hearing that
> they
> were either removed or dumbed down in 1.9).

They were, in fact, added in 1.9.
Posted by Eric Christopherson (echristopherson)
on 2012-10-10 20:37
(Received via mailing list)
On Wed, Oct 10, 2012 at 5:05 AM, Peter Zotov <whitequark@whitequark.org> 
wrote:
>>> It's neat to be able to get dirty when one needs it and feels confident
> They were, in fact, added in 1.9.
Oh, interesting.

To the OP: It's usually advised to break a method into several, if you
find that it gets too long or has too many levels of indentation.
Posted by Jim Wise (Guest)
on 2012-10-10 21:28
(Received via mailing list)
On Oct 10, 2012, at 06:05 , Peter Zotov <whitequark@whitequark.org> 
wrote:

>>> Anyway… for now, I'll just make exceptions to my indentation fixation,
>>> waiting for a freer future.
>>
>> You can use continuations (although I think I recall hearing that they
>> were either removed or dumbed down in 1.9).
>
> They were, in fact, added in 1.9.



Neither, actually -- callcc is present in both 1.8.7 and 1.9, but was 
moved from the core to a stdlib in 1.9 (the 'continuation' module).

However, callcc is not guaranteed to be present in all implementations 
(and is in fact not present in JRuby and MacRuby).

I use callcc as the basis for the (mostly humorous/proof-of-concept) 
"reconsidered" gem, which -- to the original poster's question -- adds a 
limited form of goto to ruby, and for the more serious ambit gem, which 
provides nondeterministic programming for Ruby, and is the basis for the 
in-progress rulog logic programming system for Ruby.

See:

  https://github.com/jimwise/

for more on reconsidered, ambit, and rulog.  :-)
Posted by Ryan Davis (Guest)
on 2012-10-10 23:03
(Received via mailing list)
On Oct 10, 2012, at 03:05 , Peter Zotov <whitequark@whitequark.org> 
wrote:

>>> Anyway… for now, I'll just make exceptions to my indentation fixation,
>>> waiting for a freer future.
>>
>> You can use continuations (although I think I recall hearing that they
>> were either removed or dumbed down in 1.9).
>
> They were, in fact, added in 1.9.

No, they were added MUCH earlier than 1.9.

>> RUBY_VERSION
=> "1.8.7"
>> callcc {}
=> nil

In fact, way way earlier than that:

10024 % cd ruby_1_4
10025 % ag callcc
./ChangeLog
2301:  * eval.c (rb_callcc): call scope_dup() for all scopes in
3127:  * eval.c (rb_callcc): experimental continuation support.

./eval.c
7518:rb_callcc(self)
7616:    rb_define_global_function("callcc", rb_callcc, 0);
Posted by Tony Arcieri (Guest)
on 2012-10-10 23:34
(Received via mailing list)
On Wed, Oct 10, 2012 at 2:01 PM, Ryan Davis 
<ryand-ruby@zenspider.com>wrote:

> > Eric Christopherson  10.10.2012 02:12:
> > They were, in fact, added in 1.9.
>
> No, they were added MUCH earlier than 1.9.


I'm guessing he was probably thinking of Fibers
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.