Modifying boolean values

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

Farrel Lifson wrote:

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.

In article <c2c0b66050328082336b5a5e6@mail.gmail.com>,

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

···

Farrel Lifson <farrel.lifson@gmail.com> wrote:

Farrel Lifson schrieb:

···

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

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

···

On Tue, 29 Mar 2005 03:34:46 +0900, Phil Tomson <ptkwt@aracnet.com> wrote:

In article <c2c0b66050328082336b5a5e6@mail.gmail.com>,
Farrel Lifson <farrel.lifson@gmail.com> wrote:
>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

Florian Gross schrieb:

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

Christoph wrote:

[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...