attr_accessor, but for a boolean

Discussion in 'Ruby' started by Albert Schlef, Apr 12, 2010.

  1. Let's say I have this code:

    class Mambo
    attr_accesstor :safe
    end

    Now,

    'safe', in my case, is a boolean. Problem is, the getter will be named
    'safe', whereas I want it to be 'safe?'.

    In other words, how do I make the getter 'safe?' and the setter 'safe'
    ?
    --
    Posted via http://www.ruby-forum.com/.
    Albert Schlef, Apr 12, 2010
    #1
    1. Advertising

  2. Albert Schlef

    Daniel N Guest

    [Note: parts of this message were removed to make it a legal post.]

    There's no built in way in ruby for it to know that you're going to put a
    boolean in there. You'll need to do something like

    class Mambo
    attr_writer :safe

    def safe?
    !!@safe
    end
    end

    HTH
    Daniel

    On 12 April 2010 11:00, Albert Schlef <> wrote:

    > Let's say I have this code:
    >
    > class Mambo
    > attr_accesstor :safe
    > end
    >
    > Now,
    >
    > 'safe', in my case, is a boolean. Problem is, the getter will be named
    > 'safe', whereas I want it to be 'safe?'.
    >
    > In other words, how do I make the getter 'safe?' and the setter 'safe'
    > ?
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
    Daniel N, Apr 12, 2010
    #2
    1. Advertising

  3. Albert Schlef

    Daniel N Guest

    [Note: parts of this message were removed to make it a legal post.]

    On 12 April 2010 11:10, Aaron Patterson <> wrote:

    > On Mon, Apr 12, 2010 at 10:00:06AM +0900, Albert Schlef wrote:
    > > Let's say I have this code:
    > >
    > > class Mambo
    > > attr_accesstor :safe
    > > end
    > >
    > > Now,
    > >
    > > 'safe', in my case, is a boolean. Problem is, the getter will be named
    > > 'safe', whereas I want it to be 'safe?'.
    > >
    > > In other words, how do I make the getter 'safe?' and the setter 'safe'
    > > ?

    >
    > In situations like this, I make two "getters" and leave the assignment
    > alone. Other ruby programmers expect your "setters" to be in the form
    > of "obj.safe = true", not "obj.safe(true)".
    >
    > Try something like this:
    >
    > class Mambo
    > attr_accesstor :safe
    > alias :safe? :safe
    > end
    >
    > Here it is in action:
    >
    > irb(main):001:0> class Mambo
    > irb(main):002:1> attr_accessor :safe
    > irb(main):003:1> alias :safe? :safe
    > irb(main):004:1> end
    > => nil
    > irb(main):005:0> m = Mambo.new
    > => #<Mambo:0x000001010cab50>
    > irb(main):006:0> m.safe = true
    > => true
    > irb(main):007:0> m.safe?
    > => true
    > irb(main):008:0>
    >
    > --
    > Aaron Patterson
    > http://tenderlovemaking.com/



    Unfortunately this doesn't support safe? being boolean always. It could be
    something other than true false (may not be a problem)

    If you want to use attr_accessor rather than simply aliasing the method I'd
    suggest

    def safe?
    !!safe
    end

    This way the expectation of a ? method to return a boolean is preserved.

    Cheers
    Daniel
    Daniel N, Apr 12, 2010
    #3
  4. Aaron Patterson wrote:
    > alias :safe? :safe


    Daniel wrote:
    > def safe?
    > !!@safe
    > end



    Thank you both. I wanted to make sure there's no built-in way to do
    this.

    (BTW, in Lisp (CLOS) it's possible to specify the getter/setter names.)
    --
    Posted via http://www.ruby-forum.com/.
    Albert Schlef, Apr 12, 2010
    #4
  5. Albert Schlef wrote:
    > Thank you both. I wanted to make sure there's no built-in way to do
    > this.


    Hey, I've just discovered that 'ri' tells me that Module has an
    'attr_reader?' method that creates a question-mark attribute.

    Problem is, 'ri' displays methods from everything I've installed on my
    system, so I can't know if 'attr_reader?' is provided by Ruby itself or
    by some wacky gem.
    --
    Posted via http://www.ruby-forum.com/.
    Albert Schlef, Apr 12, 2010
    #5
  6. Albert Schlef

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Mon, Apr 12, 2010 at 12:35 AM, Albert Schlef <>wrote:

    > Albert Schlef wrote:
    > > Thank you both. I wanted to make sure there's no built-in way to do
    > > this.

    >
    > Hey, I've just discovered that 'ri' tells me that Module has an
    > 'attr_reader?' method that creates a question-mark attribute.
    >
    > Problem is, 'ri' displays methods from everything I've installed on my
    > system, so I can't know if 'attr_reader?' is provided by Ruby itself or
    > by some wacky gem.
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    Doesn't work for me, so probably from some gem.

    You could do something like this:

    class Module
    def attr_accessor?(*methods)
    methods.each do |method|
    ivar = "@#{method}"
    define_method("#{method}=") { |value| instance_variable_set ivar ,
    value }
    define_method("#{method}?") { !!instance_variable_get(ivar) }
    end
    end
    end


    class Example
    attr_accessor? :abc
    end

    e = Example.new
    e.abc = true
    e.abc? # => true

    e.abc = false
    e.abc? # => false

    e.abc = 1
    e.abc? # => true

    e.abc = nil
    e.abc? # => false

    e.abc = :adsf
    e.abc? # => true




    There was also a ruby quiz about attr methods
    http://rubyquiz.com/quiz67.html And there is a gem based off of it
    http://github.com/ahoward/fattr

    I don't know where yours came from, though.
    Josh Cheek, Apr 12, 2010
    #6
  7. Albert Schlef

    Intransition Guest

    On Apr 11, 9:13=A0pm, Daniel N <> wrote:

    > Unfortunately this doesn't support safe? being boolean always. =A0It coul=

    d be
    > something other than true false (may not be a problem)
    >
    > If you want to use attr_accessor rather than simply aliasing the method I=

    'd
    > suggest
    >
    > def safe?
    > =A0 !!safe
    > end
    >
    > This way the expectation of a ? method to return a boolean is preserved.


    I used to think this too, but... I think it was Austin Ziegler who
    made the argument against using anything like "!!". In ruby it isn't
    necessary. Anything that isn't nil or false is evaluated by
    conditionals as true. I haven't once seen a case where it mattered if
    a boolean was returned rather than the underlying value.
    Intransition, Apr 12, 2010
    #7
  8. Albert Schlef

    Intransition Guest

    On Apr 11, 9:00=A0pm, Albert Schlef <> wrote:
    > Let's say I have this code:
    >
    > class Mambo
    > =A0 attr_accesstor :safe
    > end
    >
    > Now,
    >
    > 'safe', in my case, is a boolean. Problem is, the getter will be named
    > 'safe', whereas I want it to be 'safe?'.


    In Ruby 1.9, once can create writers with

    attr :x=3D

    I love this feature b/c it means I can just use #attr and not need the
    other three attr_reader, attr_writer and attr_accessor.

    It would be cool if we could make "boolean" readers too with,

    attr :x?

    (P.S. Is the attr :x=3D feature going to get back ported to 1.8.8?)
    Intransition, Apr 12, 2010
    #8
  9. On Apr 11, 7:00=A0pm, Albert Schlef <> wrote:
    > Let's say I have this code:
    >
    > class Mambo
    > =A0 attr_accesstor :safe
    > end
    >
    > Now,
    >
    > 'safe', in my case, is a boolean. Problem is, the getter will be named
    > 'safe', whereas I want it to be 'safe?'.
    >
    > In other words, how do I make the getter 'safe?' and the setter 'safe'
    > ?


    Wouldn't that have been nice?

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/5796

    Regards,

    Dan
    Daniel Berger, Apr 12, 2010
    #9
  10. Albert Schlef

    Bill Kelly Guest

    Intransition wrote:
    >>
    >> This way the expectation of a ? method to return a boolean is preserved.

    >
    > I used to think this too, but... I think it was Austin Ziegler who
    > made the argument against using anything like "!!". In ruby it isn't
    > necessary. Anything that isn't nil or false is evaluated by
    > conditionals as true. I haven't once seen a case where it mattered if
    > a boolean was returned rather than the underlying value.


    In a DRb situation, I'd rather send 'true' across the wire than
    an arbitrary object.

    Also, if the boolean value is going to be stored somewhere,
    I'd rather store a 'true' than reference an arbitrary object.

    Also, if I'm adding a temporary debug printout #{someval.inspect}
    it's nicer to see true/false in the output.


    Regards,

    Bill
    Bill Kelly, Apr 12, 2010
    #10
  11. Albert Schlef

    Intransition Guest

    On Apr 12, 1:02=A0pm, Bill Kelly <> wrote:
    > Intransition wrote:
    >
    > >> This way the expectation of a ? method to return a boolean is preserve=

    d.
    >
    > > I used to think this too, but... I think it was Austin Ziegler who
    > > made the argument against using anything like "!!". In ruby it isn't
    > > necessary. Anything that isn't nil or false is evaluated by
    > > conditionals as true. I haven't once seen a case where it mattered if
    > > a boolean was returned rather than the underlying value.

    >
    > In a DRb situation, I'd rather send 'true' across the wire than
    > an arbitrary object.


    That's an interesting point.

    > Also, if the boolean value is going to be stored somewhere,
    > I'd rather store a 'true' than reference an arbitrary object.


    I imagine the the underlying attribute (e.g. @safe) is what will be
    stored in any case, so if that isn't already false/true it probably
    won't matter in this case.

    > Also, if I'm adding a temporary debug printout #{someval.inspect}
    > it's nicer to see true/false in the output.


    At other times you might want to see the underlying attribute. It's
    easier to write '!!obj.safe?' then it is to write
    'obj.instance_eval{ @safe }'.

    I can understand wanting it either way depending on the situation. But
    for an attr method I think it's probably best to side on doing less
    rather than more, i.e. just making :a? a normal reader. But I wouldn't
    bemoan it working one way or the other really.
    Intransition, Apr 12, 2010
    #11
  12. Albert Schlef

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Mon, Apr 12, 2010 at 1:29 PM, Intransition <> wrote:

    > > it's nicer to see true/false in the output.

    >
    > At other times you might want to see the underlying attribute. It's
    > easier to write '!!obj.safe?' then it is to write
    > 'obj.instance_eval{ @safe }'.
    >
    > I can understand wanting it either way depending on the situation. But
    > for an attr method I think it's probably best to side on doing less
    > rather than more, i.e. just making :a? a normal reader. But I wouldn't
    > bemoan it working one way or the other really.
    >
    >

    You could define

    save= , the setter for @safe
    safe , the getter for @safe
    safe? , returns !!safe

    Then you can use whichever makes the most sense for your particular use.
    Josh Cheek, Apr 12, 2010
    #12
    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. J Leonard
    Replies:
    4
    Views:
    12,663
    Mark Space
    Jan 19, 2008
  2. Jim Cain
    Replies:
    0
    Views:
    92
    Jim Cain
    Jul 18, 2003
  3. David Garamond
    Replies:
    1
    Views:
    94
    Dan Doel
    Jan 25, 2004
  4. Jack, Paul
    Replies:
    2
    Views:
    105
    Robert Klemme
    Dec 16, 2004
  5. Metre Meter
    Replies:
    7
    Views:
    363
    Metre Meter
    Aug 6, 2010
Loading...

Share This Page