module Highcharts
module Option
class Title
attr_accessor :x,:y, :style, :margin, :text, :floating
def align=(align)
if !::Highcharts::ALIGNMENT.has_key? align
raise UnsupportedAlignmentError, 'Alignment not supported'
end
@align = align
end
def vertical_align=(align)
if !::Highcharts::ALIGNMENT.has_key? align
raise UnsupportedAlignmentError, 'Alignment not supported'
end
@vertical_align = align
end
def attrs
({}.extend DeepMerge).tap do |me|
me.deep_merge :title => {:align => @align} unless @align.nil?
me.deep_merge :title => {:verticalAlign => @vertical_align} unless @vertical_align.nil?
me.deep_merge :title => {:x => @x} unless @x.nil?
me.deep_merge :title => {:y => @y} unless @y.nil?
me.deep_merge :title => {:text => @text} unless @text.nil?
me.deep_merge :title => {:margin => @margin} unless @margin.nil?
me.deep_merge :title => {:style => @style} unless @style.nil?
end
end
end
end
end
# Duplication on x,y and alignments
module Highcharts
module Option
class Position
attr_accessor :x, :y
attr_reader :align, :vertical_align
def align=(align)
if !::Highcharts::ALIGNMENT.has_key? align
raise UnsupportedAlignmentError, 'Alignment not supported'
end
@align = align
end
def vertical_align=(align)
if !::Highcharts::ALIGNMENT.has_key? align
raise UnsupportedAlignmentError, 'Alignment not supported'
end
@vertical_align = align
end
def attrs
({}.extend DeepMerge).tap do |me|
me.deep_merge :position => {:align => @align} unless @align.nil?
me.deep_merge :position => {:verticalAlign => @vertical_align} unless @vertical_align.nil?
me.deep_merge :position => {:x => @x} unless @x.nil?
me.deep_merge :position => {:y => @y} unless @y.nil?
end
end
end
end
end
Refactorings
No refactoring yet !
pahanix
November 30, 2010, November 30, 2010 01:29, permalink
module Highcharts
module Option
class AlignmentStruct < Struct
# we should override ::new not #initialize
def self.new(*args)
super(:align, :vertical_align, *args)
end
def align=(align)
raise_on_unsupported_alignment(align)
self[:align] = align
end
def vertical_align=(align)
raise_on_unsupported_alignment(align)
self[:vertical_align] = align
end
def attrs
# Do you really need to extend Hash with DeepMerge here?
attributes = {}
each_pair{|member, value| attributes[member] = value if value}
{ current_object_symbol => attributes }
end
private
# Transforms Highcharts::Option::Title into :title
def current_object_symbol
self.class.to_s.split('::').last.downcase.to_sym
end
def raise_on_unsupported_alignment(align)
if !::Highcharts::ALIGNMENT.has_key? align
raise UnsupportedAlignmentError, 'Alignment not supported'
end
end
end
Title = AlignmentStruct.new(:x,:y, :style, :margin, :text, :floating)
Position = AlignmentStruct.new(:x,:y)
end
end
pahanix
November 30, 2010, November 30, 2010 11:16, permalink
Also you should transform :vertical_align into :verticalAlignin in your code
def attrs
attributes = {}
each_pair{|member, value| attributes[member] = value unless value.nil? }
attributes.empty? ? {} : { current_object_symbol => attributes }
end
This is a ruby gem I'm working on that wraps the highcharts javascript library.
1st Concern: I'm trying to provide a ruby API on top of the lib above, this is part of a larger object. I have to take this object into a hash( see #attrs ), so I can do .to_json upper in the build pipeline. I thought about just working with a hash directly underneath, but I talked out of that by a fellow ruby programmer.
I wonder if there's a better way to do this. Any thoughts?
1st Problem: As you can see there's a lot of duplication going on, but the #attrs method depends directly on
which attributes the current object has to build up a hash out of it, so it can be turned into a json, as mentioned above.
Is there a way to improve this? I could see creating modules for those identical groups, but how would attrs work on those attributes provided by the module?