Attr_reader, default attribute value, and rdoc of attribute


#1

What I want to do is create an attribute, allow it to have a default
value, and have the attribute documented as such (and not as a method)
with rdoc. So, would the proper syntax for accomplishing this
elementary feat be:

Field (row) delimiter. Default is a comma.

attr_reader fld_delimiter

:call-seq:

#   fld_delimiter
#
# Returns the field (column) delimiter.  Default is comma.
def fld_delimiter #:nodoc:
  !@fld_delimiter.nil? ? @fld_delimiter : (@fld_delimiter = ',')
end

# :call-seq:
#   fld_delimiter(String)
#
# Assign a field (column) delimiter.
def fld_delimiter=(d)
  @fld_delimiter = d
end

Thanks for your suggestions.
dvn


#2

I don’t know about rdoc, but perhaps the following might help.
See first class Test and usage, to find out if this is
what you need

#!/usr/bin/env ruby

#-----------------------------------------------
#-----------------------------------------------
module MyAccessor
def my_attribute (nou, defval=nil)
if defval == nil
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou}
end”
elsif defval.class==String
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou} || ‘#{defval}’
end”
else
code =“def #{nou} (s=nil)
@#{nou} = s || @#{nou} || #{defval}
end”
end
puts "defining ", code
class_eval code
end # def my_attr
end # module

#----------------------------------------
class Test

extend MyAccessor

my_attribute(:color, “red”)
my_attribute(:width, 20)
my_attribute(:text, “no name”)

def initialize (&block)
instance_eval(&block)
end
end

#----------------------------------

usage

puts " -------------- "
t = Test.new {
color “blue”
}
puts " -------------- "

puts t.color # => blue
puts t.width # => 20
puts t.text # => no name

t.width 50

puts t.width # => 50


#3

dkmd_nielsen wrote:

What I want to do is create an attribute, allow it to have a default
value, and have the attribute documented as such (and not as a method)
with rdoc. So, would the proper syntax for accomplishing this
elementary feat be:

Field (row) delimiter. Default is a comma.

attr_reader fld_delimiter

:call-seq:

#   fld_delimiter
#
# Returns the field (column) delimiter.  Default is comma.
def fld_delimiter #:nodoc:
  !@fld_delimiter.nil? ? @fld_delimiter : (@fld_delimiter = ',')
end

# :call-seq:
#   fld_delimiter(String)
#
# Assign a field (column) delimiter.
def fld_delimiter=(d)
  @fld_delimiter = d
end

I would tidy this up as:

attr_accessor :fld_delimiter
def fld_delimiter #:nodoc:
@fld_delimiter ||= ‘,’
end

That assumes you never want to assign nil or false as a fld_delimiter.
If you do, then

attr_accessor :fld_delimiter
def fld_delimiter #:nodoc
@fld_delimiter = ‘,’ unless defined? @fld_delimiter
@fld_delimiter
end

Another option is never to assign when defaults are being used: using a
constant lets you document the default.

DEFAULT_FLD_DELIMITER = ‘,’.freeze
attr_accessor :fld_delimiter
def fld_delimiter
defined? @fld_delimiter ? @fld_delimiter : DEFAULT_FLD_DELIMITER
end

However I think it would be simpler just to set @fld_delimiter=’,’ in
your object’s initialize method.


#4

The archetypal Ruby best-practice will look like
this:

DEFAULT_FLD_DELIMITER = ‘,’.freeze

attr_accessor :fld_delimiter

def initialize
@fld_delimiter = DEFAULT_FLD_DELIMITER
end

Another common pattern:

class Foo
DEFAULT_OPTS = {
:fld_delimiter => ‘,’,
}
def initialize(opts = {})
opts = DEFAULT_OPTS.merge(opts)
@fld_delimiter = opts[:fld_delimiter]
end
end

f = Foo.new
g = Foo.new(:fld_delimiter => ’ ')


#5

On Nov 26, 6:17 am, Brian C. removed_email_address@domain.invalid wrote:

#   fld_delimiter
def fld_delimiter=(d)

That assumes you never want to assign nil or false as a fld_delimiter.

DEFAULT_FLD_DELIMITER = ‘,’.freeze
attr_accessor :fld_delimiter
def fld_delimiter
defined? @fld_delimiter ? @fld_delimiter : DEFAULT_FLD_DELIMITER
end

However I think it would be simpler just to set @fld_delimiter=’,’ in
your object’s initialize method.

Posted viahttp://www.ruby-forum.com/.

Thanks guys. This is exactly the kind of information I’m looking
for…and need to get better at Ruby development. This is good
stuff. Thanks again.


#6

On Nov 26, 7:17 am, Brian C. removed_email_address@domain.invalid wrote:

#   fld_delimiter
def fld_delimiter=(d)

That assumes you never want to assign nil or false as a fld_delimiter.

DEFAULT_FLD_DELIMITER = ‘,’.freeze
attr_accessor :fld_delimiter
def fld_delimiter
defined? @fld_delimiter ? @fld_delimiter : DEFAULT_FLD_DELIMITER
end

However I think it would be simpler just to set @fld_delimiter=’,’ in
your object’s initialize method.

Brain is right on. The archetypal Ruby best-practice will look like
this:

DEFAULT_FLD_DELIMITER = ‘,’.freeze

attr_accessor :fld_delimiter

def initialize
@fld_delimiter = DEFAULT_FLD_DELIMITER
end


#7

dkmd_nielsen wrote:

What I want to do is create an attribute, allow it to have a default
value, and have the attribute documented as such (and not as a method)
with rdoc. So, would the proper syntax for accomplishing this
elementary feat be:

Something else to consider, along with the other suggestions, is the -A
switch in rdoc:

–accessor, -A accessorname[,…]
comma separated list of additional class methods
that should be treated like ‘attr_reader’ and
friends. Option may be repeated. Each accessorname
may have ‘=text’ appended, in which case that text
appears where the r/w/rw appears for normal accessors.

So you could define a class method just to let rdoc know that your
method should be documented as an attribute. The actual implementation
of the method can be anything.

You class method could also arrange the default value…