Forum: Ruby Redefine while

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.
3e44e24d0836528083e5b88a180770a5?d=identicon&s=25 Emil S. (emilsverige)
on 2008-11-06 16:02
Hi, is there an easy way to redefine 'while'. I have a class that uses a
while loop. In my unit test it always evaluates to false (which is
correct). I only want the loop to run once, and the enter. Just like an
if.

This is the code I've tried:


def while(condition)
  p "redefined while!"
  yield if condition
end

while true do
  p "hello"
  sleep 1
end


But it loops eternally.
Any help?
83a2263e0c04e98a344057edf62f4b9a?d=identicon&s=25 Michael G. (mguterl)
on 2008-11-06 16:09
(Received via mailing list)
On Thu, Nov 6, 2008 at 10:00 AM, Emil Sandin <esandin@gmail.com> wrote:
>  yield if condition
> end
>
> while true do
>  p "hello"
>  sleep 1
> end
>
>
> But it loops eternally.
> Any help?
The problem is that while is not a method in ruby but a keyword
[reserved word].

http://www.zenspider.com/Languages/Ruby/QuickRef.html

Michael Guterl
Jason Roelofs (Guest)
on 2008-11-06 16:10
(Received via mailing list)
On Thu, Nov 6, 2008 at 10:00 AM, Emil Sandin <esandin@gmail.com> wrote:
>  yield if condition
> --
> Posted via http://www.ruby-forum.com/.
>
>

Not possible. 'while' is a keyword, not a method.

Jason
3e44e24d0836528083e5b88a180770a5?d=identicon&s=25 Emil S. (emilsverige)
on 2008-11-06 16:21
Jason Roelofs wrote:
> On Thu, Nov 6, 2008 at 10:00 AM, Emil Sandin <esandin@gmail.com> wrote:
>>  yield if condition
>> --
>> Posted via http://www.ruby-forum.com/.
>>
>>
>
> Not possible. 'while' is a keyword, not a method.
>
> Jason

Too bad. I thought you could do anything with ruby ;)

Emil
unknown (Guest)
on 2008-11-06 16:33
(Received via mailing list)
On Thu, Nov 6, 2008 at 10:00 AM, Emil Sandin <esandin@gmail.com> wrote:
> Hi, is there an easy way to redefine 'while'. I have a class that uses a
> while loop. In my unit test it always evaluates to false (which is
> correct). I only want the loop to run once, and the enter. Just like an
> if.

As others already noted, while is a keyword not a method.  But
depending on how your code is structured you might be able to mock the
condition in your test:

$ cat foo.rb
class Foo
  attr_reader :i

  def initialize
    @i = 0
  end

  def condition
    @i < 10
  end

  def method
    while condition
      @i += 1
    end
  end
end

$ cat foo_spec.rb
require 'foo'

describe Foo do
  it "should loop once" do
    f = Foo.new
    f.i.should == 0
    f.method
    f.i.should == 10
  end

  it "should loop once" do
    f = Foo.new
    f.should_receive(:condition).and_return(true, false)
    f.i.should == 0
    f.method
    f.i.should == 1
  end
end

$ spec foo_spec.rb
..
Finished in 0.008461 seconds
2 examples, 0 failures
3e44e24d0836528083e5b88a180770a5?d=identicon&s=25 Emil S. (emilsverige)
on 2008-11-06 16:45
A good idea, but isn't working in my case. If I mock the condition I
change the behaviour of the method under test too much. But thanks
anyway!
Pascal J. Bourguignon (Guest)
on 2008-11-06 18:21
(Received via mailing list)
Emil Sandin <esandin@gmail.com> writes:

>> Jason
>
> Too bad. I thought you could do anything with ruby ;)

No.  You'd need a non-broken lisp to do that.

In Common Lisp:

(shadow 'while)
(defmacro while (condition &body body)
   `(progn
       (format t "In redefined while~%")
       (when ,condition
         ,@body)))

(while t
  'hi)
In redefined while
HI
Robert Klemme (Guest)
on 2008-11-07 00:00
(Received via mailing list)
On 06.11.2008 16:43, Emil Sandin wrote:
> A good idea, but isn't working in my case. If I mock the condition I
> change the behaviour of the method under test too much. But thanks
> anyway!

I find your approach suspicious: you write a class with a method whose
regular behavior involves executing a loop.  Then, during tests you want
the loop to not loop, i.e. you change the behavior of your method.
Strictly speaking the test result is then meaningless, because you do
not test the behavior of the method that you want to use regularly.

If there is a complex operation in the loop that you want to test
separately you should probably refactor the code.  Then you can have
your one off test.

Cheers

  robert
William James (Guest)
on 2008-11-07 04:35
(Received via mailing list)
Pascal J. Bourguignon wrote:

> >> Not possible. 'while' is a keyword, not a method.
> >>
> >> Jason
> >
> > Too bad. I thought you could do anything with ruby ;)
>
> No.  You'd need a non-broken lisp to do that.

No, you wouldn't.  For real extensibility, you need Forth.

>
> In Common Lisp:

A.k.a. Commune Lisp, Committee Lisp, and COBOL Lisp.

> In redefined while
> HI

GForth:

variable x

: try1   2 x !
  begin
    x @ 9 <
  while
    x @ .
    1 x +!
  repeat ;

: repeat  2drop drop postpone then ; immediate

: try2   2 x !
  begin
    x @ 9 <
  while
    x @ .
    1 x +!
  repeat ;

try1 cr try2

2 3 4 5 6 7 8 redefined REPEAT with repeat
2
William James (Guest)
on 2008-11-07 04:55
(Received via mailing list)
William James wrote:

> 2 3 4 5 6 7 8 redefined REPEAT with repeat
> 2

redefined REPEAT with repeat  2 3 4 5 6 7 8
2
3e44e24d0836528083e5b88a180770a5?d=identicon&s=25 Emil S. (emilsverige)
on 2008-11-07 10:30
Robert Klemme wrote:
> On 06.11.2008 16:43, Emil Sandin wrote:
>
> I find your approach suspicious: you write a class with a method whose
> regular behavior involves executing a loop.  Then, during tests you want
> the loop to not loop, i.e. you change the behavior of your method.
> Strictly speaking the test result is then meaningless, because you do
> not test the behavior of the method that you want to use regularly.
>
> If there is a complex operation in the loop that you want to test
> separately you should probably refactor the code.  Then you can have
> your one off test.
>
> Cheers
>
>   robert

That is probably a good idea.
Kaz Kylheku (Guest)
on 2008-11-07 18:30
(Received via mailing list)
On 2008-11-06, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>> Not possible. 'while' is a keyword, not a method.
>>>
>>> Jason
>>
>> Too bad. I thought you could do anything with ruby ;)
>
> No.  You'd need a non-broken lisp to do that.
>
> In Common Lisp:

Now now, Pascal; William James is a Usenet problem, not a comp.lang.ruby
problem.  It doesn't make sense to retaliate in this way. :)
This topic is locked and can not be replied to.