Make a class evaluate to false in boolean expressions

Discussion in 'Ruby' started by Matt Margolis, Oct 9, 2007.

  1. I want to have a class that always evaluates to false in boolean
    expressions. Is there a way to extend Ruby so that it evaluates an
    object of a class to false like false and nil?

    Example

    class AlwaysFalse
    end

    should_be_false = AlwaysFalse.new

    if should_be_false
    #I don't want this to ever run
    else
    #will always run
    end

    The use case for this is to have the concept of false but have it
    contain instance variables. You can't stick instance variables on
    FalseClass because it is a singleton and every use of false will
    overwrite the previous instance variable values.
    a = false
    a.name = "fish"
    b = false
    b.name = "ocean"
    #at this point in time a.name is equal to "ocean" and not "fish" like I
    want.

    This example may seem like an awful design decision but in the program I
    am writing it is important to have an interface like this to meet the
    requirements I have to code against.

    Is achieving this behavior as simple as redefining some operator methods
    like == or is this sort of behavior not possible in Ruby?

    Thank you,
    Matt Margolis
    Matt Margolis, Oct 9, 2007
    #1
    1. Advertising

  2. On 10/9/07, Matt Margolis <> wrote:
    > I want to have a class that always evaluates to false in boolean
    > expressions. Is there a way to extend Ruby so that it evaluates an
    > object of a class to false like false and nil?
    >
    > Example
    >
    > class AlwaysFalse
    > end
    >
    > should_be_false = AlwaysFalse.new
    >
    > if should_be_false
    > #I don't want this to ever run
    > else
    > #will always run
    > end
    >
    > The use case for this is to have the concept of false but have it
    > contain instance variables. You can't stick instance variables on
    > FalseClass because it is a singleton and every use of false will
    > overwrite the previous instance variable values.
    > a = false
    > a.name = "fish"
    > b = false
    > b.name = "ocean"
    > #at this point in time a.name is equal to "ocean" and not "fish" like I
    > want.
    >
    > This example may seem like an awful design decision but in the program I
    > am writing it is important to have an interface like this to meet the
    > requirements I have to code against.
    >
    > Is achieving this behavior as simple as redefining some operator methods
    > like == or is this sort of behavior not possible in Ruby?
    >

    The latter.

    OTOH:

    class Object
    def false?
    false
    end
    end

    class FalseClass
    def false?
    true
    end
    end

    class YourClass
    def false?
    true
    end
    end

    if condition.false?
    ...
    end

    Kind of annoying if you forget the .false? though. A better thing to
    do would be to figure out what you are trying to model by having
    multiple "falsy" values with some state.

    > Thank you,
    > Matt Margolis
    >
    >
    Logan Capaldo, Oct 9, 2007
    #2
    1. Advertising

  3. Logan Capaldo wrote:
    > On 10/9/07, Matt Margolis <> wrote:
    >
    >> I want to have a class that always evaluates to false in boolean
    >> expressions. Is there a way to extend Ruby so that it evaluates an
    >> object of a class to false like false and nil?
    >>
    >> Example
    >>
    >> class AlwaysFalse
    >> end
    >>
    >> should_be_false = AlwaysFalse.new
    >>
    >> if should_be_false
    >> #I don't want this to ever run
    >> else
    >> #will always run
    >> end
    >>
    >> The use case for this is to have the concept of false but have it
    >> contain instance variables. You can't stick instance variables on
    >> FalseClass because it is a singleton and every use of false will
    >> overwrite the previous instance variable values.
    >> a = false
    >> a.name = "fish"
    >> b = false
    >> b.name = "ocean"
    >> #at this point in time a.name is equal to "ocean" and not "fish" like I
    >> want.
    >>
    >> This example may seem like an awful design decision but in the program I
    >> am writing it is important to have an interface like this to meet the
    >> requirements I have to code against.
    >>
    >> Is achieving this behavior as simple as redefining some operator methods
    >> like == or is this sort of behavior not possible in Ruby?
    >>
    >>

    > The latter.
    >
    > OTOH:
    >
    > class Object
    > def false?
    > false
    > end
    > end
    >
    > class FalseClass
    > def false?
    > true
    > end
    > end
    >
    > class YourClass
    > def false?
    > true
    > end
    > end
    >
    > if condition.false?
    > ...
    > end
    >
    > Kind of annoying if you forget the .false? though. A better thing to
    > do would be to figure out what you are trying to model by having
    > multiple "falsy" values with some state.
    >
    >
    >> Thank you,
    >> Matt Margolis
    >>
    >>
    >>

    >
    >

    I don't want to have to call .false? though. Ideally what I would like
    to be able to do is just use the object in boolean expressions like
    false. Anyone have any idea if this is at all possible?

    Matt Margolis
    Matt Margolis, Oct 9, 2007
    #3
  4. On 10/9/07, Matt Margolis <> wrote:
    > Logan Capaldo wrote:
    > > On 10/9/07, Matt Margolis <> wrote:
    > >> Is achieving this behavior as simple as redefining some operator methods
    > >> like == or is this sort of behavior not possible in Ruby?
    > >>
    > >>

    > > The latter.
    > >


    Quoting myself. In other words, no you can't do it.
    Logan Capaldo, Oct 9, 2007
    #4
  5. On 09.10.2007 18:12, Logan Capaldo wrote:
    > On 10/9/07, Matt Margolis <> wrote:
    >> Logan Capaldo wrote:
    >>> On 10/9/07, Matt Margolis <> wrote:
    >>>> Is achieving this behavior as simple as redefining some operator methods
    >>>> like == or is this sort of behavior not possible in Ruby?
    >>>>
    >>>>
    >>> The latter.
    >>>

    >
    > Quoting myself. In other words, no you can't do it.


    An alternative approach might be to use 'case' expressions instead of
    'if' and implement #=== properly in that class.

    Matt, what are you implementing? Why is this functionality crucial?

    Kind regards

    robert
    Robert Klemme, Oct 9, 2007
    #5
  6. Matt Margolis

    John Joyce Guest

    On Oct 9, 2007, at 10:53 AM, Matt Margolis wrote:

    > I want to have a class that always evaluates to false in boolean
    > expressions. Is there a way to extend Ruby so that it evaluates an
    > object of a class to false like false and nil?
    >
    > Example
    >
    > class AlwaysFalse
    > end
    >
    > should_be_false = AlwaysFalse.new
    >
    > if should_be_false
    > #I don't want this to ever run
    > else
    > #will always run
    > end

    This is your design problem.
    You can't change the language to do what it doesn't do.
    What you want is probably not a class if it always returns false.
    You want a constant value.
    You can create a class with an instance or class variable that
    happens to be a constant. (no setter, only a getter)
    so you might do

    The problem is your if will go to else if the should_be_false is
    false. not clear logic in the code.
    Just do it the Ruby way, create a method or function:
    my_class.false?
    or
    false?( my_arg )

    This way the logic is more obvious and clear like natural language.
    John Joyce, Oct 9, 2007
    #6
  7. Robert Klemme wrote:
    > On 09.10.2007 18:12, Logan Capaldo wrote:
    >> On 10/9/07, Matt Margolis <> wrote:
    >>> Logan Capaldo wrote:
    >>>> On 10/9/07, Matt Margolis <> wrote:
    >>>>> Is achieving this behavior as simple as redefining some operator
    >>>>> methods
    >>>>> like == or is this sort of behavior not possible in Ruby?
    >>>>>
    >>>>>
    >>>> The latter.
    >>>>

    >>
    >> Quoting myself. In other words, no you can't do it.

    >
    > An alternative approach might be to use 'case' expressions instead of
    > 'if' and implement #=== properly in that class.
    >
    > Matt, what are you implementing? Why is this functionality crucial?
    >
    > Kind regards
    >
    > robert
    >

    I can't really get into specifics but basically I am doing something
    like the following

    module PrimitiveExtensions
    attr_accessor :name
    def to_extended_primitive(name)
    @name = name
    return self
    end


    I then mix this in to String, Fixnum, Float etc...

    MyClass contains
    def my_val=(obj)
    obj.to_extended_primitive("MyVal")
    end
    def other_val=(obj)
    obj.to_extended_primitive("OtherVal")
    end

    The purpose of all of this is to unify an interface so that I can store
    primitive values along with a name without having to go through a
    container class to get at the value.
    a = MyClass.new.my_val = 7
    and then later be able to go back and do something like
    a.name and get back "MyVal"


    This approach works for all the base types except for true and false
    since they are Singletons so I can't store a @name on them.
    Matt Margolis, Oct 9, 2007
    #7
  8. On 09.10.2007 19:41, Matt Margolis wrote:
    > Robert Klemme wrote:
    >> On 09.10.2007 18:12, Logan Capaldo wrote:
    >>> On 10/9/07, Matt Margolis <> wrote:
    >>>> Logan Capaldo wrote:
    >>>>> On 10/9/07, Matt Margolis <> wrote:
    >>>>>> Is achieving this behavior as simple as redefining some operator
    >>>>>> methods
    >>>>>> like == or is this sort of behavior not possible in Ruby?
    >>>>>>
    >>>>>>
    >>>>> The latter.
    >>>>>
    >>>
    >>> Quoting myself. In other words, no you can't do it.

    >>
    >> An alternative approach might be to use 'case' expressions instead of
    >> 'if' and implement #=== properly in that class.
    >>
    >> Matt, what are you implementing? Why is this functionality crucial?
    >>
    >> Kind regards
    >>
    >> robert
    >>

    > I can't really get into specifics but basically I am doing something
    > like the following
    >
    > module PrimitiveExtensions
    > attr_accessor :name
    > def to_extended_primitive(name)
    > @name = name
    > return self
    > end
    >
    >
    > I then mix this in to String, Fixnum, Float etc...
    >
    > MyClass contains
    > def my_val=(obj)
    > obj.to_extended_primitive("MyVal")
    > end
    > def other_val=(obj)
    > obj.to_extended_primitive("OtherVal")
    > end


    This seems a strange way to use assignment since you do not modify the
    receiver but the sender. I'd say this will likely lead to hard to code
    that is hard to understand.

    > The purpose of all of this is to unify an interface so that I can store
    > primitive values along with a name without having to go through a
    > container class to get at the value.
    > a = MyClass.new.my_val = 7
    > and then later be able to go back and do something like
    > a.name and get back "MyVal"
    >
    > This approach works for all the base types except for true and false
    > since they are Singletons so I can't store a @name on them.


    I doubt this approach works for all basic types since you will get
    aliasing effects with Fixnums, i.e. you set the name in one place and it
    will be visible on all other places as well as Fixnums are singletons
    per value.

    I do not know why you are so eager to have the attribute stored in the
    primitive value. Considering what I have seen of your requirements I
    would probably do something like this

    NamedValue = Struct.new :value, :name

    Kind regards

    robert
    Robert Klemme, Oct 9, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mehul
    Replies:
    0
    Views:
    755
    mehul
    May 3, 2004
  2. Paminu

    Which numbers evaluate to true and false?

    Paminu, Oct 4, 2005, in forum: C Programming
    Replies:
    22
    Views:
    805
    August Karlstrom
    Oct 6, 2005
  3. Replies:
    49
    Views:
    2,150
    public boolean
    Nov 21, 2008
  4. Gustavo Narea
    Replies:
    4
    Views:
    1,875
    Arnaud Delobelle
    Apr 28, 2009
  5. Replies:
    3
    Views:
    149
Loading...

Share This Page