Forum: Ruby Cond loop vs iterator and scope questions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
2cef22e5d84ec3cdc107a5f9f97537e5?d=identicon&s=25 toddkennethbenson (Guest)
on 2005-11-19 20:10
(Received via mailing list)
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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 james (Guest)
on 2005-11-19 20:19
(Received via mailing list)
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
6b4566518f6675477dab9b8ba813cf3c?d=identicon&s=25 ruby.brian (Guest)
on 2005-11-19 20:37
(Received via mailing list)
On 19/11/05, Todd <toddkennethbenson@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/
2cef22e5d84ec3cdc107a5f9f97537e5?d=identicon&s=25 toddkennethbenson (Guest)
on 2005-11-19 22:26
(Received via mailing list)
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
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 vjoel (Guest)
on 2005-11-19 22:30
(Received via mailing list)
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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 james (Guest)
on 2005-11-19 22:30
(Received via mailing list)
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
2d532341317628fbb2cb22ec427a1d62?d=identicon&s=25 langstefan (Guest)
on 2005-11-19 22:30
(Received via mailing list)
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
2cef22e5d84ec3cdc107a5f9f97537e5?d=identicon&s=25 toddkennethbenson (Guest)
on 2005-11-19 22:48
(Received via mailing list)
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
4299e35bacef054df40583da2d51edea?d=identicon&s=25 james (Guest)
on 2005-11-19 22:57
(Received via mailing list)
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 Gray II
2cef22e5d84ec3cdc107a5f9f97537e5?d=identicon&s=25 toddkennethbenson (Guest)
on 2005-11-19 23:15
(Received via mailing list)
James Edward Gray 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 Gray II

Thanks again,
Todd
This topic is locked and can not be replied to.