Opposite of ||= pattern?


#1

A cheap just-in-time initialization trick is the “||=” trick:

def add_name(n)
@name ||= Array.new
@name << n
end

Now, how would you do the opposite of this pattern? More specifically,
what
kind of construct would evaluate to a true value once, and then nil from
then on? I came upon this in the context of for loops, where I want a
one-time “starting” value to be present the first time through the loop,
then nil. And I wanted to do it in a cool way - i.e. not just assign
the
value to nil at the end of the loop, though of course that is the
easiest
way.

Any thoughts?

Justin


#2

You could make a class “Once” to wrap your value.
Or something cheesy like this:

def name
(x, @name = @name, nil)[0]
end


#3

Actually, I like using .first instead of [0] a tad better.


#4

On Wed, 29 Mar 2006, Justin B. wrote:

one-time “starting” value to be present the first time through the loop,
then nil. And I wanted to do it in a cool way - i.e. not just assign the
value to nil at the end of the loop, though of course that is the easiest
way.

Any thoughts?

Justin

harp:~ > ruby -e’ 3.times{ p( @x ? nil : @x=42) } ’
42
nil
nil

regards.

-a


#5

On 3/28/06, Matthew M. removed_email_address@domain.invalid wrote:

You could make a class “Once” to wrap your value.

class Object
def once
@used ? nil : (@used = true; self)
end
end

test = true

3.times { p test.once }
=> true
=> nil
=> nil


#6

On 3/28/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

then on? I came upon this in the context of for loops, where I want a
one-time “starting” value to be present the first time through the loop,
then nil. And I wanted to do it in a cool way - i.e. not just assign the
value to nil at the end of the loop, though of course that is the easiest
way.

harp:~ > ruby -e’ 3.times{ p( @x ? nil : @x=42) } ’
42
nil
nil

ruby -e’first = true; 3.times { p first &&= nil }’

The opposite of ||= is &&=; it may not be appropriate for the
requested purpose, though. It allows for a “change only if set” sort
of test. I think I’ve used it once.

-austin


#7

On Sat, 1 Apr 2006, Austin Z. wrote:

harp:~ > ruby -e’ 3.times{ p( @x ? nil : @x=42) } ’
42
nil
nil

ruby -e’first = true; 3.times { p first &&= nil }’

The opposite of ||= is &&=; it may not be appropriate for the
requested purpose, though. It allows for a “change only if set” sort
of test. I think I’ve used it once.

well heck - just used it for the first time today!

i guess the OP didn’t actually want the literal opposite though…

regards.

-a


#8

On Mar 28, 2006, at 5:53 PM, removed_email_address@domain.invalid wrote:

harp:~ > ruby -e’ 3.times{ p( @x ? nil : @x=42) } ’
42
nil
nil

As an aside I was playing with ara’s code (tried to put it in a
method) and I got a toggle variable:
irb(main):006:0> def once
irb(main):007:1> @x = @x ? nil : 1
irb(main):008:1> end
irb(main):009:0> once
=> 1
irb(main):010:0> once
=> nil
irb(main):011:0> once
=> 1
irb(main):012:0> once
=> nil
irb(main):013:0> once
=> 1