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
> 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
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/
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
> 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
> 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
> 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
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
> 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
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