Martin said:
This solution is what I was looking for.
With a bit of work, I will be able to write code like this :
Hi Marc,
I'd try to keep it simple:
class A
def initialize(param_a, param_b, options = {})
@x = options[:x] || 50 # defaults to 50 if not specified
@y = options[:y] || 100
@z = options[:z] || 'red'
puts "Initialized with #{@x}/#{@y}/#{@z}"
end
end
Use default values is a goog idea. The problem is, you have to write the
code for @x, @y and @z.
My version is now this one :
I have three classes :
GUI_Object > GUI_Object_Graphic > Picture
The purpose of the code is to avoid to write a lot of code when you are
working on classes like Picture.
(I know, I don't optimize my code, if you have better solution, it would
be nice.)
class GUI_Object
attr_accessor
arent
@accessors = [
arent]
def initialize(parent=nil, hash=nil)
@parent = parent
hash = param_hash_1(parent, hash)
modify_accessor(hash)
end
def param_hash_1(parent, hash)
if hash.is_a?(Hash)
return hash
elsif parent.is_a?(Hash)
@parent = nil
return parent
end
return nil
end
def modify_accessor(hash)
return if hash == nil
hash.each do |key, val|
if self.class.check_accessor(key) == true
# Here's the 7stud function :
send("#{key}=", val)
else
raise("unknown accessor for class #{self.class}: #{key}")
end
end
end
def self.check_accessor(acc)
if self.accessor != nil and self.accessor.include?(acc)
return true
else
if self != GUI_Object
return true if self.ancestors[1].check_accessor(acc) == true
end
end
return false
end
def self.accessor
return @accessors
end
end
class GUI_Object_Graphic < GUI_Object
attr_reader :x
attr_reader :y
attr_accessor :width
attr_accessor :height
@accessors = [:x, :y, :width, :height]
def initialize(parent=nil, x=0, y=0, width=0, height=0, hash=nil)
@x = x
@y = y
@width = width
@height = height
hash = param_hash(x, y, width, height, hash)
@x = 0 if @x == nil
@y = 0 if @y == nil
@width = 0 if @width == nil
@height = 0 if @height == nil
super(parent, hash)
end
def param_hash(x, y, width, height, hash)
if hash.is_a?(Hash)
return hash
elsif x.is_a?(Hash)
@x = 0
return x
elsif y.is_a?(Hash)
@y = 0
return y
elsif width.is_a?(Hash)
@width = 0
return width
elsif height.is_a?(Hash)
@height = 0
return height
end
return nil
end
end
class Picture < GUI_Object_Graphic
attr_accessor :bg_color
attr_accessor :cadre
attr_accessor :marges
attr_accessor :image
attr_accessor :zoom
# I ONLY have to create THIS list to use the attributes I want
@accessors = [:bg_color,
icture, :zoom]
# So, it's really, really not difficult
def initialize(parent=nil, x=0, y=0, width=0, height=0, hash=nil)
# Default values
@bg_color = nil
@zoom = 1
super
@marges = [0, 0, 0, 0]
@cadre = nil
end
end
So I can use these codes to create a Picture :
x = y = width = height = 0
a = Picture.new(nil, x, y, width, height)
a = Picture.new(nil, x, y, :zoom => 2, :width => 30, :bg_color => "red")
I'm not using a class variable like @@accessors, because of the problems
with class variables.
With this code, people can easily create new classes like Picture. And
with a simple list like @accessors = [:bg_color,
icture, :zoom], they
can allow to use only the attributes they want.
It's part of my code to create a super-easy-to-use GUI working with a
video game graphical library.
Here's a screenshot :
http://i291.photobucket.com/albums/ll318/KingKadelfek/screen05-f95306.png
I want the users able to create new components (such as Picture), so I
try to find the most easiest way.