Hello, just 2 simple questions…
-
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.
-
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
On Nov 19, 2005, at 1:07 PM, Todd wrote:
Hello, just 2 simple questions…
- 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.
- 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 G. II
On 19/11/05, Todd [email protected] wrote:
Hello, just 2 simple questions…
- 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.
- 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/
James Edward G. II wrote:
On Nov 19, 2005, at 1:07 PM, Todd wrote:
Hello, just 2 simple questions…
- 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
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 G. II
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
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
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
On Nov 19, 2005, at 3:47 PM, Todd wrote:
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 G. II
James Edward G. II wrote:
yield
def foo
a = 1
a = yield a
p a
end
=> nil
foo do |var| var + 1 end
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 G. II
Thanks again,
Todd
Brian Schröder wrote:
that belong to the calling object? Something similar to Array#map! Or
self[index] = block[element]
or even more concise
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