Ticket #10424: documenting_cattr_accessors.rb
| File documenting_cattr_accessors.rb, 9.8 kB (added by toolmantim, 2 years ago) |
|---|
| Line | |
|---|---|
| 1 | # Currently a whole bunch of Rails config options aren't documented. This is due to RDoc not picking up comments on cattr_accessor. Here's a bit of a look at the options. |
| 2 | # |
| 3 | # Run rdoc over it to read the docs and see the results of the different options. |
| 4 | # |
| 5 | # Tim Lucas <t.lucas@toolmantim.com> |
| 6 | |
| 7 | require 'rubygems' |
| 8 | gem 'activesupport' |
| 9 | require 'activesupport' |
| 10 | |
| 11 | class Class |
| 12 | # Defines a class attribute accessor method and sets the class attribute's |
| 13 | # default by calling the class attribute writer method, such as <tt>self.option=</tt>. |
| 14 | # |
| 15 | # The class attribute writer method must be defined before calling this method. |
| 16 | # |
| 17 | # Without this convience method you'd typically do: |
| 18 | # class Mailer |
| 19 | # # Sets whether to perform deliveries of outgoing mail |
| 20 | # def self.perform_deliveries=(perform_deliveries) |
| 21 | # @@perform_deliveries = perform_deliveries |
| 22 | # end |
| 23 | # def self.perform_deliveries |
| 24 | # @@perform_deliveries |
| 25 | # end |
| 26 | # @@perform_deliveries = true |
| 27 | # end |
| 28 | # |
| 29 | # The equivalent to the above code but using cattr_reader_with_default is: |
| 30 | # class Mailer |
| 31 | # # Sets whether to perform deliveries of outgoing mail |
| 32 | # def self.perform_deliveries=(perform_deliveries) |
| 33 | # @@perform_deliveries = perform_deliveries |
| 34 | # end |
| 35 | # cattr_reader_with_default :perform_deliveries, true |
| 36 | # end |
| 37 | def cattr_reader_with_default(sym, default) |
| 38 | cattr_reader sym |
| 39 | class_eval(<<-EOS, __FILE__, __LINE__) |
| 40 | self.#{sym} = default |
| 41 | EOS |
| 42 | end |
| 43 | end |
| 44 | |
| 45 | # Currently a whole bunch of Rails config options aren't documented. This is due to RDoc not picking up comments on <tt>cattr_accessor</tt>. |
| 46 | # |
| 47 | # Some common examples might be <tt>ActionView::Base.field_error_proc</tt> and <tt>ActiveRecord::Base.colorize_logging</tt> which currently are only documented via the source, blogs and google. |
| 48 | # |
| 49 | # Possible solutions: |
| 50 | # * Move the comment from the <tt>cattr_accessor</tt> into an rdoc "Configuration" section on Base |
| 51 | # * Lose the connection between code+comment (bad for maintenance) |
| 52 | # * The cattr_accessor may be defined in any extension module so documentation is very far from its source code |
| 53 | # * This is the approach for <tt>ActionMailer</tt> but it works because its mostly in the one file |
| 54 | # * Copy + paste the comment from the <tt>cattr_accessor</tt> into an rdoc "Configuration" section on Base |
| 55 | # * Copy + paste is bad |
| 56 | # * The cattr_accessor may be defined in any extension module so documentation is very far from its source code |
| 57 | # * Patch RDoc to pick up cattr_accessor comments |
| 58 | # * Use class/module writer and reader methods and manually set default |
| 59 | # * RDoc documents both config option readers and writers |
| 60 | # * Bloaty |
| 61 | # * e.g. ClassWriterAndReaderMethods |
| 62 | # * Use class/module writer and some convenenience method |
| 63 | # * RDoc only documents config option writers |
| 64 | # * e.g. ClassWriterAndAttrConvenienceMethod |
| 65 | # * Leave them as is (i.e. using an RDoc above <tt>cattr_accessor</tt>) |
| 66 | # * Everything stays undocumented ); |
| 67 | # * e.g. AttributeAccessors |
| 68 | # |
| 69 | # Considering most config options are now using <tt>instance_writer => false</tt> its probably a good time for a refactoring |
| 70 | module ActiveSupportConfigDocsDemo |
| 71 | # The current way of documenting config options. |
| 72 | # |
| 73 | # The ultimate in minimalism, though we all have to suffer for it. |
| 74 | class AttributeAccessors |
| 75 | # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and |
| 76 | # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as |
| 77 | # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember |
| 78 | # that this is a global setting for all Active Records. |
| 79 | cattr_accessor :primary_key_prefix_type, :instance_writer => false |
| 80 | @@primary_key_prefix_type = nil |
| 81 | |
| 82 | # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all |
| 83 | # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace |
| 84 | # for tables in a shared database. By default, the prefix is the empty string. |
| 85 | cattr_accessor :table_name_prefix, :instance_writer => false |
| 86 | @@table_name_prefix = "" |
| 87 | |
| 88 | # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", |
| 89 | # "people_basecamp"). By default, the suffix is the empty string. |
| 90 | cattr_accessor :table_name_suffix, :instance_writer => false |
| 91 | @@table_name_suffix = "" |
| 92 | |
| 93 | # Indicates whether table names should be the pluralized versions of the corresponding class names. |
| 94 | # If true, the default table name for a +Product+ class will be +products+. If false, it would just be +product+. |
| 95 | # See table_name for the full rules on table/class naming. This is true, by default. |
| 96 | cattr_accessor :pluralize_table_names, :instance_writer => false |
| 97 | @@pluralize_table_names = true |
| 98 | end |
| 99 | |
| 100 | # A straight ruby way of specifying config options. |
| 101 | # |
| 102 | # It's pretty darn bloaty, though it has the advantage of both writer and reader methods getting picked up by RDoc. |
| 103 | class ClassWriterAndReaderMethods |
| 104 | class << self |
| 105 | # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and |
| 106 | # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as |
| 107 | # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember |
| 108 | # that this is a global setting for all Active Records. |
| 109 | def primary_key_prefix_type=(primary_key_prefix_type) |
| 110 | @@primary_key_prefix_type = primary_key_prefix_type |
| 111 | end |
| 112 | def primary_key_prefix_type |
| 113 | @@primary_key_prefix_type |
| 114 | end |
| 115 | @@primary_key_prefix_type = nil |
| 116 | |
| 117 | # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all |
| 118 | # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace |
| 119 | # for tables in a shared database. By default, the prefix is the empty string. |
| 120 | def table_name_prefix=(table_name_prefix) |
| 121 | @@table_name_prefix = table_name_prefix |
| 122 | end |
| 123 | def table_name_prefix |
| 124 | @@table_name_prefix |
| 125 | end |
| 126 | @@table_name_prefix = "" |
| 127 | |
| 128 | # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", |
| 129 | # "people_basecamp"). By default, the suffix is the empty string. |
| 130 | def table_name_suffix=(table_name_suffix) |
| 131 | @@table_name_suffix = table_name_suffix |
| 132 | end |
| 133 | def table_name_suffix |
| 134 | @@table_name_suffix |
| 135 | end |
| 136 | @@table_name_suffix = "" |
| 137 | |
| 138 | # Indicates whether table names should be the pluralized versions of the corresponding class names. |
| 139 | # If true, the default table name for a +Product+ class will be +products+. If false, it would just be +product+. |
| 140 | # See table_name for the full rules on table/class naming. This is true, by default. |
| 141 | def pluralize_table_names=(pluralize_table_names) |
| 142 | @@pluralize_table_names = pluralize_table_names |
| 143 | end |
| 144 | def pluralize_table_names |
| 145 | @@pluralize_table_names |
| 146 | end |
| 147 | @@pluralize_table_names = true |
| 148 | end |
| 149 | end |
| 150 | |
| 151 | # Using standard Ruby to declaring option writers and Class.cattr_reader_with_default to specify the reader method and default value. |
| 152 | # |
| 153 | # At least 5 times sexier than the ClassWriterAndReaderMethods approach. |
| 154 | class ClassWriterAndAttrConvenienceMethod |
| 155 | # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and |
| 156 | # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as |
| 157 | # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember |
| 158 | # that this is a global setting for all Active Records. |
| 159 | def self.primary_key_prefix_type=(primary_key_prefix_type) |
| 160 | @@primary_key_prefix_type = primary_key_prefix_type |
| 161 | end |
| 162 | cattr_reader_with_default :primary_key_prefix_type, nil |
| 163 | |
| 164 | # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all |
| 165 | # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace |
| 166 | # for tables in a shared database. By default, the prefix is the empty string. |
| 167 | def self.table_name_prefix=(table_name_prefix) |
| 168 | @@table_name_prefix = table_name_prefix |
| 169 | end |
| 170 | cattr_reader_with_default :table_name_prefix, "" |
| 171 | |
| 172 | # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", |
| 173 | # "people_basecamp"). By default, the suffix is the empty string. |
| 174 | def self.table_name_suffix=(table_name_suffix) |
| 175 | @@table_name_suffix = table_name_suffix |
| 176 | end |
| 177 | cattr_reader_with_default :table_name_suffix, "" |
| 178 | |
| 179 | # Indicates whether table names should be the pluralized versions of the corresponding class names. |
| 180 | # If true, the default table name for a +Product+ class will be +products+. If false, it would just be +product+. |
| 181 | # See table_name for the full rules on table/class naming. This is true, by default. |
| 182 | def self.pluralize_table_names=(pluralize_table_names) |
| 183 | @@pluralize_table_names = pluralize_table_names |
| 184 | end |
| 185 | cattr_reader_with_default :pluralize_table_names, true |
| 186 | end |
| 187 | end |
| 188 | |
| 189 | if $0 == __FILE__ |
| 190 | require 'test/unit' |
| 191 | class SomeClass #:nodoc: |
| 192 | def self.option=(option) |
| 193 | @@option = option |
| 194 | end |
| 195 | cattr_reader_with_default :option, "Value" |
| 196 | end |
| 197 | class CAttrReaderWithDefaultTest < Test::Unit::TestCase #:nodoc: |
| 198 | def test_should_create_and_accessor_and_set_the_default |
| 199 | assert_equal "Value", SomeClass.option |
| 200 | end |
| 201 | end |
| 202 | end |