Forum: Ruby attr_reader, default attribute value, and rdoc of attribute

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C0f4cef363d69500730aa9afa9cf7774?d=identicon&s=25 dkmd_nielsen (Guest)
on 2008-11-26 12:46
(Received via mailing list)
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
8bb088c70909f7fed70f1cd10edf80cb?d=identicon&s=25 cibercitizen1 (Guest)
on 2008-11-26 13:05
(Received via mailing list)
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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-11-26 13:21
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.
C0f4cef363d69500730aa9afa9cf7774?d=identicon&s=25 dkmd_nielsen (Guest)
on 2008-11-26 14:01
(Received via mailing list)
On Nov 26, 6:17 am, Brian Candler <b.cand...@pobox.com> 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.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Thomas Sawyer (7rans)
on 2008-11-26 14:19
(Received via mailing list)
On Nov 26, 7:17 am, Brian Candler <b.cand...@pobox.com> 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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-11-26 15:07
> 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 => ' ')
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2008-11-26 18:45
(Received via mailing list)
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....
This topic is locked and can not be replied to.