Class: Perfume::SuperObject
- Inherits:
-
Object
- Object
- Perfume::SuperObject
- Defined in:
- lib/perfume/super_object.rb
Overview
Public: Premise is tha using method arguments sucks because you need to remember the order, sucks even more when you might have lot of them (like structure/service initializers).
It’s often seen in ruby to declare classes that inherit from Struct. There we have problem of arguments order. Maybe I wanna specify defaults? Maybe I wanna pass only one argument from the middle of the list? For such cases people use OpenStruct or third-party stuff like Hashie::Dash. Not a good idea either because those classes are bloated with useless methods.
Here’s how this super object works:
class Women < SuperObject(:name, :surname)
args :married
def title
@married ? 'Mrs.' : 'Miss'
end
def to_s
[ title, name, surname ].join(' ')
end
end
ada = Women.new(name: "Ada", surname: "Lovelace", married: true)
ada.name # => "Ada"
ada.surname # => "Lovelace"
ada.to_s # => "Mrs. Ada Lovelace"
mary = Women.new(name: "mary", surname: "Cassat", married: false)
mary.to_s # => "Miss Mary Cassat"
mary.married # => NoMethodError
Women.new(unknown: 'Something') # => ArgumentError
By default ‘args` method defines only instance variables. Then we have `args_accessor`, which is called for all class parameters, `args_reader` and `args_writer` if you need to expose some stuff.
Class Method Summary collapse
-
.args(*names) ⇒ Object
Public: Defines unaccessible arguments.
-
.args_accessor(*names) ⇒ Object
Public: Defines given init arguments alongside with accessor methods.
-
.args_reader(*names) ⇒ Object
Public: Defines given init arguments alongside with reader method.
-
.args_writer(*names) ⇒ Object
Public: Defines given init arguments alongside with writer method.
-
.init_args ⇒ Object
Public: Returns list of defined arguments.
Instance Method Summary collapse
-
#defaults ⇒ Object
Public: Override it with your own default arguments.
-
#init ⇒ Object
Public: Extra initialization.
-
#initialize(args = {}) ⇒ SuperObject
constructor
A new instance of SuperObject.
Constructor Details
#initialize(args = {}) ⇒ SuperObject
Returns a new instance of SuperObject.
70 71 72 73 74 75 76 77 |
# File 'lib/perfume/super_object.rb', line 70 def initialize(args = {}) args.symbolize_keys! unknown_args = args.keys - self.class.init_args raise ArgumentError, "Unknown arguments: #{unknown_args.map(&:inspect).join(', ')}" unless unknown_args.empty? args = defaults.symbolize_keys.merge(args) self.class.init_args.each { |name| instance_variable_set("@#{name}", args[name]) } init end |
Class Method Details
.args(*names) ⇒ Object
Public: Defines unaccessible arguments.
47 48 49 |
# File 'lib/perfume/super_object.rb', line 47 def self.args(*names) init_args.concat(names) end |
.args_accessor(*names) ⇒ Object
Public: Defines given init arguments alongside with accessor methods.
52 53 54 55 56 |
# File 'lib/perfume/super_object.rb', line 52 def self.args_accessor(*names) names = names.map(&:to_sym) args(*names) attr_accessor(*names) end |
.args_reader(*names) ⇒ Object
Public: Defines given init arguments alongside with reader method.
59 60 61 62 |
# File 'lib/perfume/super_object.rb', line 59 def self.args_reader(*names) args(*names) attr_reader(*names) end |
.args_writer(*names) ⇒ Object
Public: Defines given init arguments alongside with writer method.
65 66 67 68 |
# File 'lib/perfume/super_object.rb', line 65 def self.args_writer(*names) args(*names) attr_writer(*names) end |
.init_args ⇒ Object
Public: Returns list of defined arguments. Note that superclass arguments are inherited by child class.
42 43 44 |
# File 'lib/perfume/super_object.rb', line 42 def self.init_args @init_args ||= superclass.respond_to?(:init_args) ? superclass.init_args.dup : [] end |
Instance Method Details
#defaults ⇒ Object
Public: Override it with your own default arguments.
84 85 86 |
# File 'lib/perfume/super_object.rb', line 84 def defaults {} end |
#init ⇒ Object
Public: Extra initialization.
80 81 |
# File 'lib/perfume/super_object.rb', line 80 def init end |