---
title: "Rails 5.2 default option to module & class attribute accessors"
description:
  "Rails 5.2 now supports specifying a default value using 'default' option for
  the module and class macros viz. mattr_accessor, mattr_reader, mattr_writer,
  cattr_accessor, cattr_reader, and cattr_writer respectively."
canonical_url: "https://www.bigbinary.com/blog/rails-5-2-adds-default-options-to-module-and-class-attribute-accessors"
markdown_url: "https://www.bigbinary.com/blog/rails-5-2-adds-default-options-to-module-and-class-attribute-accessors.md"
---

# Rails 5.2 default option to module & class attribute accessors

Rails 5.2 now supports specifying a default value using 'default' option for the
module and class macros viz. mattr_accessor, mattr_reader, mattr_writer,
cattr_accessor, cattr_reader, and cattr_writer respectively.

- Author: Vishal Telangre
- Published: February 27, 2018
- Categories: Rails 5.2, Rails

When DHH introduced
[support for specifying a default value for class_attribute](https://blog.bigbinary.com/2018/02/21/rails-5-2-supports-specifying-default-value-for-a-class_attribute.html),
Genadi Samokovarov
[brought to notice](https://github.com/rails/rails/pull/29270#issuecomment-304705841)
that the module and class attribute accessor macros also support specifying a
default value but using a block and not with a `default` option.

To have consistent and symmetrical behaviour across all the attribute
extensions, it was decided to support specifying a default value using `default`
option for all the module and class attribute macros as well.

`mattr_accessor`, `mattr_reader` and `mattr_writer` macros generate getter and
setter methods at the module level.

Similarly, `cattr_accessor`, `cattr_reader`, and `cattr_writer` macros generate
getter and setter methods at the class level.

## Before Rails 5.2

Before Rails 5.2, this is how we would set the default values for the module and
class attribute accessor macros.

```ruby
module ActivityLoggerHelper
  mattr_accessor :colorize_logs
  mattr_writer :log_ip { false }

  self.colorize_logs = true
end

class ActivityLogger
  include ActivityLoggerHelper

  cattr_writer :logger { Logger.new(STDOUT) }
  cattr_accessor :level
  cattr_accessor :settings
  cattr_reader :pid { Process.pid }

  @@level = Logger::DEBUG
  self.settings = {}
end
```

## After Rails 5.2

We can still set a default value of a module or class attribute accessor by
providing a block. In this
[pull request](https://github.com/rails/rails/pull/29294), support for
specifying a default value using a new `default` option has been introduced.

So instead of

```ruby
cattr_writer :logger { Logger.new(STDOUT) }
```

or

```ruby
cattr_writer :logger
self.logger = Logger.new(STDOUT)
```

or

```ruby
cattr_writer :logger
@@logger = Logger.new(STDOUT)
```

we can now easily write

```ruby
cattr_writer :logger, default: Logger.new(STDOUT)
```

Same applies to the other attribute accessor macros like `mattr_accessor`,
`mattr_reader`, `mattr_writer`, `cattr_accessor`, and `cattr_reader`.

Note that, the old way of specifying a default value using the block syntax will
work but will not be documented anywhere.

Also, note that if we try to set the default value by both ways i.e. by
providing a block as well as by specifying a `default` option; the value
provided by `default` option will always take the precedence.

```ruby
mattr_accessor(:colorize_logs, default: true) { false }
```

Here, `@@colorize_logs` would be set with `true` as per the above precedence
rule.

[Here is a test](https://github.com/rails/rails/blob/b6b0c99ff3e8ace3f42813154dbe4b8ad6a98e6c/activesupport/test/core_ext/module/attribute_accessor_test.rb#L45-L47)
which verifies this behavior.

Finally, here is simplified version using the new `default` option.

```ruby
module ActivityLoggerHelper
  mattr_accessor :colorize_logs, default: true
  mattr_writer :log_ip, default: false
end

class ActivityLogger
  include ActivityLoggerHelper

  cattr_writer :logger, default: Logger.new(STDOUT)
  cattr_accessor :level, default: Logger::DEBUG
  cattr_accessor :settings, default: {}
  cattr_reader :pid, default: Process.pid
end
```

## Links

- [Human page](https://www.bigbinary.com/blog/rails-5-2-adds-default-options-to-module-and-class-attribute-accessors)
