Modifying boolean values

F

Farrel Lifson

Hi Rubyists,

Is it possible to somehow ducktype an object so that it behaves like a
boolean object (ie true or false)?

The problem I'm having at the moment is that I'd like to have a
modified boolean value so that instead of returning "true" or "false",
my objects to_s returns "1" when true and "0" when false. I've tried
the following

@myTrue = true
def @myTrue.to_s
return "1"
end

however creating an anonymous class doesn't seem to be allowed and
this affected the results of the original true instance (it now
returns "1" as well) which I'd prefer stayed untouched.

I thought of using numbers such as 1 for true but 0 is not false in a
boolean expression.

So is there a way to create an object that acts like a true or false
when in boolean expression but still be modified without changing the
true or false global objects? Or is there any function called in the
evaluation of boolean expresssions which would allow me to ducktype a
modified object?

Thanks in advance,
Farrel
 
P

Phil Tomson

Hi Rubyists,

Is it possible to somehow ducktype an object so that it behaves like a
boolean object (ie true or false)?

The problem I'm having at the moment is that I'd like to have a
modified boolean value so that instead of returning "true" or "false",
my objects to_s returns "1" when true and "0" when false. I've tried
the following

@myTrue = true
def @myTrue.to_s
return "1"
end

however creating an anonymous class doesn't seem to be allowed and
this affected the results of the original true instance (it now
returns "1" as well) which I'd prefer stayed untouched.

I thought of using numbers such as 1 for true but 0 is not false in a
boolean expression.

So is there a way to create an object that acts like a true or false
when in boolean expression but still be modified without changing the
true or false global objects? Or is there any function called in the
evaluation of boolean expresssions which would allow me to ducktype a
modified object?

You say you want to have it return a string "1", but what if you return
an Integer 1 instead? TrueClass doesn't have a to_i method defined in
it, so you could do:

class TrueClass
def to_i
return 1
end
end

Alternatively, TrueClass doesn't have a to_str method defined either, so
if you _really_ need a string you could define:

class TrueClass
def to_str
return "1"
end
end

....but of course, if you're looking to use this in places where to_s is
automatically called (like in puts) then it won't work right.


The problem is that 'true' and 'false' are treated as boolean literals,
so whenever you use them you get a TrueClass or FalseClass. I think that
means that you can't just have a MyTrueClass that inherits from TrueClass
and have it work right - it won't. That means you have to define new
methods on TrueClass/FalseClass.

I think your best bet is to define the to_i method on TrueClass (as
above) because that's really what you're trying to get, an integer. Then
if you need a string you can convert the resulting integer to a string
explicitly.


Phil
 
F

Florian Gross

Farrel said:
Is it possible to somehow ducktype an object so that it behaves like a
boolean object (ie true or false)?

Everything but nil and false is true so you can indeed create custom
true values, but you will not be able to create custom false values.
This logic is hard-wired via the RTEST() macro for performance reasons.
Patching Ruby ought to be relatively simple (just change the macro to to
a method call to #to_bool), however.
however creating an anonymous class doesn't seem to be allowed and
this affected the results of the original true instance (it now
returns "1" as well) which I'd prefer stayed untouched.

There's always just one true, one nil and one false object and their
meta-classes are TrueClass, NilClass and FalseClass respectively.
So is there a way to create an object that acts like a true or false
when in boolean expression but still be modified without changing the
true or false global objects? Or is there any function called in the
evaluation of boolean expresssions which would allow me to ducktype a
modified object?

Unfortunately, there isn't in standard Ruby.

The feature would as well be useful for doing full object proxies
(WeakRefs to false or nil currently misbehave).

I suppose that you might be able to get this changed in standard Ruby if
you find that the slowdown caused by changing the RTEST() macro is not
too high. But I'm not sure if it is like that. Perhaps you could also
special case true, false and nil so that they would not go through the
RTEST() method call -- after all you already have one of those values in
most cases.
 
F

Farrel Lifson

Yeah I think this is my best bet at the moment. Florian's suggestion
is a little bit too much effort to implement at the moment for a small
change like this.

Farrel
 
C

Christoph

Farrel said:
Hi Rubyists,

Is it possible to somehow ducktype an object so that it behaves like a
boolean object (ie true or false)?

The problem I'm having at the moment is that I'd like to have a
modified boolean value so that instead of returning "true" or "false",
my objects to_s returns "1" when true and "0" when false. I've tried
the following

@myTrue = true
def @myTrue.to_s
return "1"
end

however creating an anonymous class doesn't seem to be allowed and
this affected the results of the original true instance (it now
returns "1" as well) which I'd prefer stayed untouched.

I thought of using numbers such as 1 for true but 0 is not false in a
boolean expression.

So is there a way to create an object that acts like a true or false
when in boolean expression but still be modified without changing the
true or false global objects? Or is there any function called in the
evaluation of boolean expresssions which would allow me to ducktype a
modified object?

Thanks in advance,
Farrel
 
C

Christoph

Florian said:
Unfortunately, there isn't in standard Ruby.

The feature would as well be useful for doing full object proxies
(WeakRefs to false or nil currently misbehave).

I suppose that you might be able to get this changed in standard Ruby
if you find that the slowdown caused by changing the RTEST() macro is
not too high. But I'm not sure if it is like that. Perhaps you could
also special case true, false and nil so that they would not go
through the RTEST() method call -- after all you already have one of
those values in most cases.
You can get an idea about the performance penalties from
my implementation using "false" flags, akin to frozen and
tainted flags.

www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/279

/Christoph
 
F

Florian Gross

Christoph said:
[User-definable false values]
You can get an idea about the performance penalties from
my implementation using "false" flags, akin to frozen and
tainted flags.

www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/279

Interesting, I think it might be nice to implement it like that in Rite.
I think it might be a good idea to use more than 32 bits for flags in
the future, anyway, as it might be a good thing to have some of them
available to the GC and for other purposes...
 

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
474,169
Messages
2,570,920
Members
47,463
Latest member
FinleyMoye

Latest Threads

Top