Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Cond loop vs iterator and scope questions

0 views
Skip to first unread message

Todd

unread,
Nov 19, 2005, 2:02:28 PM11/19/05
to
Hello, just 2 simple questions...

1. Why is it that you cannot have an iterator nested inside a
conditional loop? I'm sure there's a good reason, but it escapes me.

2. Is it possible in Ruby, from within a block, to modify variables
that belong to the calling object? Something similar to Array#map! Or
must this be done in C?

Thanks,
Todd

James Edward Gray II

unread,
Nov 19, 2005, 2:16:18 PM11/19/05
to
On Nov 19, 2005, at 1:07 PM, Todd wrote:

> Hello, just 2 simple questions...
>
> 1. Why is it that you cannot have an iterator nested inside a
> conditional loop? I'm sure there's a good reason, but it escapes me.

You can. Please show us the code and we'll help you find the problem.

> 2. Is it possible in Ruby, from within a block, to modify variables
> that belong to the calling object? Something similar to
> Array#map! Or
> must this be done in C?

Ruby's blocks are closures and thus can modify local variables from
the binding of the caller. Here again if you show us the code, we
can probably help you find The Ruby Way of achieving your goal...

James Edward Gray II


Brian Schröder

unread,
Nov 19, 2005, 2:36:33 PM11/19/05
to
On 19/11/05, Todd <toddkenn...@yahoo.com> wrote:
> Hello, just 2 simple questions...
>
> 1. Why is it that you cannot have an iterator nested inside a
> conditional loop? I'm sure there's a good reason, but it escapes me.
>

As james said, you can.

> 2. Is it possible in Ruby, from within a block, to modify variables
> that belong to the calling object? Something similar to Array#map! Or
> must this be done in C?
>

Array.map! could be implemented like this. (In reality its part of
Enumerable, but that does not matter here)

class Array
def map!(&block)
changed = false
self.each_with_index do | element, index |
self[index] = block[element]
changed ||= (self[index] == element)
end
if changed
self
else
nil
end
end
end

or even more concise

class Array
def map!(&block)
changed = nil
self.each_with_index do | element, index |
changed ||= ((self[index] = block[element]) == element)
end
self if changed
end
end

but the middle line would I would consider to be golfed too much and
badly readable, though I like the last line.

cheers,

Brian

> Thanks,
> Todd
>
>
>


--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/


Todd

unread,
Nov 19, 2005, 4:18:48 PM11/19/05
to

James Edward Gray II wrote:
> On Nov 19, 2005, at 1:07 PM, Todd wrote:
>
> > Hello, just 2 simple questions...
> >
> > 1. Why is it that you cannot have an iterator nested inside a
> > conditional loop? I'm sure there's a good reason, but it escapes me.
>
> You can. Please show us the code and we'll help you find the problem.

irb(main):001:0> f=[1,2]
=> [1, 2]
irb(main):002:0> while 1 do
irb(main):003:1* f.each do |i|
irb(main):004:1* end
SyntaxError: compile error
(irb):004: syntax error
from (irb):004

It seems like irb is trying to close the while with that first end
instead of the f.each. Same thing happens with syntax coloring in vim.

Todd

Joel VanderWerf

unread,
Nov 19, 2005, 4:26:22 PM11/19/05
to
Todd wrote:

> irb(main):001:0> f=[1,2]
> => [1, 2]
> irb(main):002:0> while 1 do

^^ No "do" here.

> irb(main):003:1* f.each do |i|
> irb(main):004:1* end
> SyntaxError: compile error
> (irb):004: syntax error
> from (irb):004

irb(main):001:0> f=[1,2]


=> [1, 2]
irb(main):002:0> while 1

irb(main):003:1> f.each do |i|
irb(main):004:2* end
irb(main):005:1> end
IRB::Abort: abort then interrupt!!
from /usr/local/lib/ruby/1.8/irb.rb:81:in `irb_abort'
from /usr/local/lib/ruby/1.8/irb.rb:241:in `signal_handle'
from /usr/local/lib/ruby/1.8/irb.rb:66:in `start'
from /usr/local/lib/ruby/1.8/irb.rb:65:in `call'
from (irb):2

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


James Edward Gray II

unread,
Nov 19, 2005, 4:29:16 PM11/19/05
to
On Nov 19, 2005, at 3:22 PM, Todd wrote:

> irb(main):001:0> f=[1,2]
> => [1, 2]
> irb(main):002:0> while 1 do

There's a syntax error in the above line. It's just while ... end,
not while do ... end.

Hope that helps.

James Edward Gray II

Stefan Lang

unread,
Nov 19, 2005, 4:29:53 PM11/19/05
to
On Saturday 19 November 2005 22:22, Todd wrote:
[...]

> irb(main):001:0> f=[1,2]
> => [1, 2]
> irb(main):002:0> while 1 do
^^
remove this "do"

> irb(main):003:1* f.each do |i|
> irb(main):004:1* end
> SyntaxError: compile error

^^^^^^^^^^^


> (irb):004: syntax error
>         from (irb):004

It's a syntax error, as correctly identified.
Syntax of "while" expression is:

while <condition>
<expressions>
end

Your example:

while 1
f.each do |i|
# do something with i and eventually break
end
end

or:

loop do
f.each do |i|
# do something with i and eventually break
end
end

HTH,
Stefan


Todd

unread,
Nov 19, 2005, 4:44:46 PM11/19/05
to

OK, maybe I'm going about it the wrong way. I specified it wrong in
the original post anyway. What I want to do is have the block be able
to modify the variables in the method that's yielding to it.

Like:

def foo
a = 1
yield
#block does something with a, such that this a is now a new value,
say add 1
a
end

foo { #some code here }

=> 2

After looking at your code, I think I can accomplish this more
elegantly (by inheriting from Array). But out of curiosity, is it
possible to do the above?

Thanks,
Todd

James Edward Gray II

unread,
Nov 19, 2005, 4:53:19 PM11/19/05
to
On Nov 19, 2005, at 3:47 PM, Todd wrote:

> OK, maybe I'm going about it the wrong way. I specified it wrong in
> the original post anyway. What I want to do is have the block be able
> to modify the variables in the method that's yielding to it.
>
> Like:
>
> def foo
> a = 1
> yield
> #block does something with a, such that this a is now a new value,
> say add 1
> a
> end
>
> foo { #some code here }
>
> => 2

Use block parameters for this:

>> def foo
>> a = 1

>> a = yield a
>> p a
>> end
=> nil
>> foo do |var| var + 1 end
2
=> nil

> After looking at your code, I think I can accomplish this more
> elegantly (by inheriting from Array).

It can be tricky, inheriting from Ruby's core classes and thus is
probably better avoided. Favor composition over inheritance.

James Edward Gray II


Todd

unread,
Nov 19, 2005, 5:11:29 PM11/19/05
to

James Edward Gray II wrote:

This is in fact how I'm doing it now, but I guess I was trying to avoid
having to do:

a = yield a

since this will be a large iteration and I'm worried the GC won't keep
up.

> It can be tricky, inheriting from Ruby's core classes and thus is
> probably better avoided. Favor composition over inheritance.
>

Yeah, I suppose have some pondering to do.

> James Edward Gray II

Thanks again,
Todd

0 new messages