Evaluation in boolean context

hi there!

would it be possible to modify how an object gets evaluated in
boolean context? i know that by default only nil and false are
evaluated as false, all others are true. however, i'd like to change
that behaviour for a (yet unimplemented) BooleanFlag object which
behaves just like true or false (according to its current value or
"state") with the added ability of easily swapping state.

it's not that difficult to implement a class that provides the state
swapping, but how to grasp that "evaluation in boolean context" kind
of thing? is there any method getting called, so i can override it?

the idea is as follows:

b = BooleanFlag.new false # create object, initially being "false"
puts "true" if b # this is the heavy part, since b (as a
                           # regular object) is always "true"
b.swap! # now b's state is "true" ...
puts "true" if b # ... and this *correctly* prints "true"

any insights? additionally, hints on how to address such issues on
my own are very welcome. i'm quite new to ruby (coming from perl),
but i definitely love it - especially the metaprogramming stuff :wink:
so maybe there's a means of digging into such internals i'm not yet
aware of.

TIA
jens

···

--
Jens Wille, Dipl.-Bibl. (FH)
prometheus - Das verteilte digitale Bildarchiv für Forschung & Lehre
An St. Laurentius 4, 50931 Köln
Tel.: +49 (0)221 470-6668, E-Mail: jens.wille@uni-koeln.de
http://www.prometheus-bildarchiv.de/

I'm not an expert myself, but couldn't you use a normal variable which
is assigned a value of either true or false?

b = false

puts "true" if b

b = !b

puts "true" if b

···

On 10/10/06, jens wille <jens.wille@uni-koeln.de> wrote:

hi there!

would it be possible to modify how an object gets evaluated in
boolean context? i know that by default only nil and false are
evaluated as false, all others are true. however, i'd like to change
that behaviour for a (yet unimplemented) BooleanFlag object which
behaves just like true or false (according to its current value or
"state") with the added ability of easily swapping state.

--
Bira

http://sinfoniaferida.blogspot.com

hi there!

would it be possible to modify how an object gets evaluated in
boolean context? i know that by default only nil and false are
evaluated as false, all others are true. however, i'd like to change
that behaviour for a (yet unimplemented) BooleanFlag object which
behaves just like true or false (according to its current value or
"state") with the added ability of easily swapping state.

it's not that difficult to implement a class that provides the state
swapping, but how to grasp that "evaluation in boolean context" kind
of thing? is there any method getting called, so i can override it?

the idea is as follows:

b = BooleanFlag.new false # create object, initially being "false"
puts "true" if b # this is the heavy part, since b (as a
                           # regular object) is always "true"
b.swap! # now b's state is "true" ...
puts "true" if b # ... and this *correctly* prints "true"

This has come up frequently in the past. The short story is that there is no way to do exactly that because of performance reasons. All sorts of things have been proposed including a method to_b defined in Object as "return self" and which is automatically called in every boolean context.

any insights? additionally, hints on how to address such issues on
my own are very welcome. i'm quite new to ruby (coming from perl),
but i definitely love it - especially the metaprogramming stuff :wink:
so maybe there's a means of digging into such internals i'm not yet
aware of.

You can still use the #to_b pattern explicitly. This is probably the cleanest solution:

BooleanFlag = Struct.new(:flag) do
   def swap!() self.flag = !flag end
   alias :to_b :flag
end

>> f = BooleanFlag.new false
=> #<struct BooleanFlag flag=false>
>> f.to_b
=> false
>> f.swap!
=> true
>> f.to_b
=> true

Alternatively / additionally you can define methods on your flag class similar to what Smalltalk does:

BooleanFlag = Struct.new(:flag) do
   def swap!() self.flag = !flag end
   alias :to_b :flag
   def iff() yield if to_b; self end
   def els() yield unless to_b; end
end

>> f=BooleanFlag.new false
=> #<struct BooleanFlag flag=false>
>> f.iff do puts "yes" end.els do puts "no" end
no
=> nil

Frankly, I never felt the need for any of these. Maybe you present your business case and we can propose some other solution.

Kind regards

  robert

···

On 10.10.2006 14:50, jens wille wrote:

Bira [10/10/06 14:58]:

I'm not an expert myself, but couldn't you use a normal variable
which is assigned a value of either true or false?

b = false

puts "true" if b

b = !b

yeah, but that's exactly what i want to avoid :wink:

thanks anyway!
jens

···

--
Jens Wille, Dipl.-Bibl. (FH)
prometheus - Das verteilte digitale Bildarchiv für Forschung & Lehre
An St. Laurentius 4, 50931 Köln
Tel.: +49 (0)221 470-6668, E-Mail: jens.wille@uni-koeln.de
http://www.prometheus-bildarchiv.de/

hi robert!

Robert Klemme [10/10/06 15:10]:

This has come up frequently in the past. The short story is that
there is no way to do exactly that because of performance
reasons. All sorts of things have been proposed including a
method to_b defined in Object as "return self" and which is
automatically called in every boolean context.

i've read some of these postings, but felt they didn't add much to
what i wanted to achieve.

You can still use the #to_b pattern explicitly. This is probably
the cleanest solution:

yes, it probably is. however, i had kind of hoped that there would
be a nice solution that fit more in my usage example. maybe i just
have to drop that :wink: thanks for your suggestions!

Frankly, I never felt the need for any of these. Maybe you
present your business case and we can propose some other
solution.

well, actually i don't have the need either. i tried to do it just
for the fun of it - to explore ruby's possibilites and play around a
bit. i mean, as long as it can be achieved in another way there
simply is no need for any more "sophisticated" solution, is it? what
kind of bugged me was that "flag = !flag" part, but obviously i just
have to stick with it...

cheers
jens

···

--
Jens Wille, Dipl.-Bibl. (FH)
prometheus - Das verteilte digitale Bildarchiv für Forschung & Lehre
An St. Laurentius 4, 50931 Köln
Tel.: +49 (0)221 470-6668, E-Mail: jens.wille@uni-koeln.de
http://www.prometheus-bildarchiv.de/

Some observations on booleans in Ruby, Smalltalk, and self:

http://talklikeaduck.denhaven2.com/articles/2006/10/10/boolean-implementations-ruby-smalltak-and-self

···

On 10/10/06, Robert Klemme <shortcutter@googlemail.com> wrote:

Alternatively / additionally you can define methods on your flag class
similar to what Smalltalk does:

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Rick DeNatale wrote:

···

On 10/10/06, Robert Klemme <shortcutter@googlemail.com> wrote:

Alternatively / additionally you can define methods on your flag class
similar to what Smalltalk does:

Some observations on booleans in Ruby, Smalltalk, and self:

http://talklikeaduck.denhaven2.com/articles/2006/10/10/boolean-implementations-ruby-smalltak-and-self

Rick, thanks for the interesting read! My gut feeling told me to better use "similar" and not "like" or "exactly". :-)))

Kind regards

  robert