Redefine while

E

Emil Sandin

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?
 
M

Michael Guterl

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?
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
 
J

Jason Roelofs

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?

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

Jason
 
B

brabuhr

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
 
E

Emil Sandin

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!
 
P

Pascal J. Bourguignon

Emil Sandin said:
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
 
R

Robert Klemme

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
 
W

William James

Pascal said:
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.
(shadow 'while)
(defmacro while (condition &body body)
`(progn
(format t "In redefined while~%")
(when ,condition
,@body)))

(while t
'hi)
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
 
E

Emil Sandin

Robert said:
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.
 
K

Kaz Kylheku

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. :)
 

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
473,770
Messages
2,569,585
Members
45,080
Latest member
mikkipirss

Latest Threads

Top