Cond loop vs iterator and scope questions

T

Todd

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
 
J

James Edward Gray II

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
 
B

Brian Schröder

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 =3D false
self.each_with_index do | element, index |
self[index] =3D block[element]
changed ||=3D (self[index] =3D=3D element)
end
if changed
self
else
nil
end
end
end

or even more concise

class Array
def map!(&block)
changed =3D nil
self.each_with_index do | element, index |
changed ||=3D ((self[index] =3D block[element]) =3D=3D 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
 
T

Todd

James said:
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
 
J

Joel VanderWerf

Todd said:
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
 
J

James Edward Gray II

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
 
S

Stefan Lang

]
irb(main):001:0> f=3D[1,2]
=3D> [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
=A0 =A0 =A0 =A0 from (irb):004

It's a syntax error, as correctly identified.
Syntax of "while" expression is:
=20
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
 
T

Todd

Brian said:
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

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
 
J

James Edward Gray II

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:
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
 
T

Todd

James said:
Use block parameters for this:

2
=> nil

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
 

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,197
Messages
2,571,040
Members
47,634
Latest member
RonnyBoelk

Latest Threads

Top