attr_accessor, but for a boolean

A

Albert Schlef

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'
?
 
D

Daniel N

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

Daniel N

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

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>


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
 
A

Albert Schlef

Albert said:
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.
 
J

Josh Cheek

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

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

Intransition

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

Intransition

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?)
 
B

Bill Kelly

Intransition said:
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
 
I

Intransition

d.

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

Josh Cheek

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

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.
 

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
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top