I'm new to Ruby. I'm looking for an elegant solution to a simple
problem.
I have some classes like this one in my code:
class A
attr_reader :a1, a2
def initialize(a1, a2) @a1 = a1 @a2 = a2
end
end
I'm looking for a way in order not to have to define the initialize
method in each class. Struct doesn't fit my needs since due to single
inheritance I can't have any other superclass, and I would like to.
You could create an attr_initializer, something like:
module MyInitSystem
# extend hack
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
attr_reader :attr_initializers
def attr_initializer(*args) @attr_initializers ||= @attr_initializers.concat(args)
attr_reader *args
end
end
def initialize(*args)
self.class.attr_initializers.each_with_index do |a,i|
instance_variable_set("@#{a}", args[i])
end
end
end
class A
include MyInitSystem
attr_initializer :a, :b
end
Albeit, I'd use a hash to populate my object by var name.
T.
···
On Oct 13, 5:20 am, arcadiorubiogar...@gmail.com wrote:
Hi everyone,
I'm new to Ruby. I'm looking for an elegant solution to a simple
problem.
I have some classes like this one in my code:
class A
attr_reader :a1, a2
def initialize(a1, a2) @a1 = a1 @a2 = a2
end
end
I'm looking for a way in order not to have to define the initialize
method in each class. Struct doesn't fit my needs since due to single
inheritance I can't have any other superclass, and I would like to.
Don't know if this has been done before, but here's a quick stab I took at it:
require 'generator'
module InitializesWith
def initializes_with(*params)
define_method :initialize do |*args|
iterator = SyncEnumerator.new(params, args)
iterator.each do |param, arg|
instance_variable_set "@#{param}", arg
end
end
end
end
class Class
include InitializesWith
end
class C
attr_reader :x, :y, :z
initializes_with :x, :y, :z
end
obj = C.new(1,2,3)
obj.x # => 1
obj.y # => 2
obj.z # => 3
Any good?
Ashley
···
On Oct 13, 2007, at 1:20 pm, arcadiorubiogarcia@gmail.com wrote:
Hi everyone,
I'm new to Ruby. I'm looking for an elegant solution to a simple
problem.
I have some classes like this one in my code:
class A
attr_reader :a1, a2
def initialize(a1, a2) @a1 = a1 @a2 = a2
end
end
I'm looking for a way in order not to have to define the initialize
method in each class. Struct doesn't fit my needs since due to single
inheritance I can't have any other superclass, and I would like to.
You mentioned both wanting to be able to inherit from another class
and that you don't want to define initialize, so will all of the
classes you wish to inherit from not need initialization?
···
On Oct 13, 8:19 am, arcadiorubiogar...@gmail.com wrote:
Hi everyone,
I'm new to Ruby. I'm looking for an elegant solution to a simple
problem.
I have some classes like this one in my code:
class A
attr_reader :a1, a2
def initialize(a1, a2) @a1 = a1 @a2 = a2
end
end
I'm looking for a way in order not to have to define the initialize
method in each class. Struct doesn't fit my needs since due to single
inheritance I can't have any other superclass, and I would like to.
class Class
def generate_initialize(*vars)
define_method(:initialize) do |*args|
vars.zip(args) do |var, arg|
instance_variable_set("@#{var}", arg)
end
end
end
end
module InitializesWith
def initializes_with(*params)
define_method :initialize do |*args|
iterator = SyncEnumerator.new(params, args)
iterator.each do |param, arg|
instance_variable_set "@#{param}", arg
end
end
end
end
class Class
include InitializesWith
end
This:
class C
attr_reader :x, :y, :z
initializes_with :x, :y, :z
end
evaluates to a Proc object, due to initializes_with implementation. I
guess it would be better to return nil at the end. Just a minor
aesthetic detail as I said.
class Class
def generate_initialize(*vars)
define_method(:initialize) do |*args|
vars.zip(args) do |var, arg|
instance_variable_set("@#{var}", arg)
end
end
end
end
class C
attr_reader *initializes_with(:x, :y, :z)
end
T.
···
On Oct 13, 7:55 am, arcadiorubiogar...@gmail.com wrote:
Thank you both for your replies.
Just a minor detail regarding:
> require 'generator'
> module InitializesWith
> def initializes_with(*params)
> define_method :initialize do |*args|
> iterator = SyncEnumerator.new(params, args)
> iterator.each do |param, arg|
> instance_variable_set "@#{param}", arg
> end
> end
> end
> end
> class Class
> include InitializesWith
> end
This:
> class C
> attr_reader :x, :y, :z
> initializes_with :x, :y, :z
> end
evaluates to a Proc object, due to initializes_with implementation. I
guess it would be better to return nil at the end. Just a minor
aesthetic detail as I said.
I'm trying to enhance the previous solution (shown again at the end).
I'd like to call the initialize method of the superclass from the
generated initialize. For the moment it's ok to call it without
parameters. Simply placing super inside the method definition doesn't
work. Can anyone explain me how to do it. Thanks in advance.
def initialize_with(*params)
define_method(:initialize) do |*args|
if args.size != params.size then
raise ArgumentError.new("wrong number of arguments"\
" (#{args.size} for #{params.size})")
end
params.zip(args) do |param, arg|
instance_variable_set("@#{param}", arg)
end
end
return params
end
def initialize_with(*params)
define_method(:initialize) do |*args|
if args.size != params.size then
raise ArgumentError.new("wrong number of arguments"\
" (#{args.size} for #{params.size})")
end
super() if defined?(super)
params.zip(args) do |param, arg|
instance_variable_set("@#{param}", arg)
end
end
return params
end
The "()" on super clears the auto-passing of parameters.
T.
···
On Oct 31, 4:10 pm, arcadiorubiogar...@gmail.com wrote:
Hi again,
I'm trying to enhance the previous solution (shown again at the end).
I'd like to call the initialize method of the superclass from the
generated initialize. For the moment it's ok to call it without
parameters. Simply placing super inside the method definition doesn't
work. Can anyone explain me how to do it. Thanks in advance.
I'm trying to enhance the previous solution (shown again at the end).
I'd like to call the initialize method of the superclass from the
generated initialize. For the moment it's ok to call it without
parameters. Simply placing super inside the method definition doesn't
work. Can anyone explain me how to do it. Thanks in advance.
Why doesn't it work?
def initialize_with(*params)
define_method(:initialize) do |*args|
if args.size != params.size then
raise ArgumentError.new("wrong number of arguments"\
" (#{args.size} for #{params.size})")
end
super() if defined?(super)
params.zip(args) do |param, arg|
instance_variable_set("@#{param}", arg)
end
end
return params
end
The "()" on super clears the auto-passing of parameters.
It seems to work (if this is what you meant):
module HasInitializeWith
def initialize_with(*params)
define_method(:initialize) do |*args|
if args.size != params.size then
raise ArgumentError.new("wrong number of arguments"\
" (#{args.size} for #{params.size})")
end
super() if defined?(super)
params.zip(args) do |param, arg|
instance_variable_set("@#{param}", arg)
end
end
return params
end
end
class A
extend HasInitializeWith
self.initialize_with :foo
end
p A.new(3) # ==> #<A:0xb7c28cbc @foo=3>
···
On Oct 31, 4:10 pm, arcadiorubiogar...@gmail.com wrote:
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
On 31 oct, 21:53, Joel VanderWerf <vj...@path.berkeley.edu> wrote:
Trans wrote:
> On Oct 31, 4:10 pm, arcadiorubiogar...@gmail.com wrote:
>> Hi again,
>> I'm trying to enhance the previous solution (shown again at the end).
>> I'd like to call the initialize method of the superclass from the
>> generated initialize. For the moment it's ok to call it without
>> parameters. Simply placing super inside the method definition doesn't
>> work. Can anyone explain me how to do it. Thanks in advance.
> Why doesn't it work?
> def initialize_with(*params)
> define_method(:initialize) do |*args|
> if args.size != params.size then
> raise ArgumentError.new("wrong number of arguments"\
> " (#{args.size} for #{params.size})")
> end
> super() if defined?(super)
> params.zip(args) do |param, arg|
> instance_variable_set("@#{param}", arg)
> end
> end
> return params
> end
> The "()" on super clears the auto-passing of parameters.
It seems to work (if this is what you meant):
module HasInitializeWith
def initialize_with(*params)
define_method(:initialize) do |*args|
if args.size != params.size then
raise ArgumentError.new("wrong number of arguments"\
" (#{args.size} for #{params.size})")
end
super() if defined?(super)
params.zip(args) do |param, arg|
instance_variable_set("@#{param}", arg)
end
end
return params
end
end
class A
extend HasInitializeWith
self.initialize_with :foo
end
p A.new(3) # ==> #<A:0xb7c28cbc @foo=3>
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407