Is there a more 'DRY' way to do the following in ruby?
#!/usr/bin/env ruby
class Volume
attr_accessor :name, :size, :type, :owner, :date_created, :date_modified, :iscsi_target, :iscsi_portal
SYSTEM = 0
DATA = 1
def initialize(args={:type => SYSTEM})
@name = args[:name]
@size = args[:size]
@type = args[:type]
@owner = args[:owner]
@iscsi_target = args[:iscsi_target]
@iscsi_portal = args[:iscsi_portal]
end
def inspect
return {:name => @name,
:size => @size,
:type => @type,
:owner => @owner,
:date_created => @date_created,
:date_modified => @date_modified,
:iscsi_target => @iscsi_target,
:iscsi_portal => @iscsi_portal }
end
def to_json
self.inspect.to_json
end
end
new is a class method, which generally creates an instance of the class (this deals with the tricky stuff like allocating memory that Ruby shields you from so you don't have to get too dirty). Then, initialize , an instance method, tells the object to set its internal state up according to the parameters requested.
verb. ini·tial·ize i-ˈni-shə-ˌlīz. initialized; initializing. transitive verb. : to set (something, such as a computer program counter) to a starting position, value, or configuration.
Ruby Class VariablesClass variables begin with @@ and must be initialized before they can be used in method definitions. Referencing an uninitialized class variable produces an error. Class variables are shared among descendants of the class or module in which the class variables are defined.
Whenever you see a long list of things like that, usually you can roll it all up into a singular Array:
class Volume
ATTRIBUTES = [
:name, :size, :type, :owner, :date_created, :date_modified,
:iscsi_target, :iscsi_portal
].freeze
ATTRIBUTES.each do |attr|
attr_accessor attr
end
SYSTEM = 0
DATA = 1
DEFAULTS = {
:type => SYSTEM
}.freeze
def initialize(args = nil)
# EDIT
# args = args ? DEFAULTS : DEFAULTS.merge(args) # Original
args = args ? DEFAULTS.merge(args) : DEFAULTS
ATTRIBUTES.each do |attr|
if (args.key?(attr))
instance_variable_set("@#{attr}", args[attr])
end
end
end
def inspect
ATTRIBUTES.inject({ }) do |h, attr|
h[attr] = instance_variable_get("@#{attr}")
h
end
end
def to_json
self.inspect.to_json
end
end
Manipulating instance variables is pretty straightforward after that.
class Volume
FIELDS = %w( name size type owner iscsi_target iscsi_portal date_create date_modified)
SYSTEM = 0
DATA = 1
attr_accessor *FIELDS
def initialize( args= { :type => SYSTEM } )
args.each_pair do | key, value |
self.send("#{key}=", value) if self.respond_to?("#{key}=")
end
end
def inspect
FIELDS.inject({}) do | hash, field |
hash.merge( field.to_sym => self.send(field) )
end.inspect
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With