[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Generation of initialize

arcadio

10/13/2007 12:19:00 PM

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.

Any suggestions?

Thanks in advance.

12 Answers

Trans

10/13/2007 12:42:00 PM

0



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.
>
> Any suggestions?

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.


Ashley Moran

10/13/2007 12:42:00 PM

0

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.
>
> Any suggestions?
>
> Thanks in advance.
>
>

Hi

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


--
blog @ http://aviewfro...
linked-in @ http://www.linkedin.com/in/a...
currently @ home


arcadio

10/13/2007 2:51:00 PM

0

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.

Trans

10/13/2007 4:00:00 PM

0



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.

Return the attributes instead and you can do:

class C
attr_reader *initializes_with(:x, :y, :z)
end

T.


Brian Adkins

10/13/2007 5:54:00 PM

0

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.

Are you looking for something like the following?

class A
auto_attr_reader :a1, :a2
end

a = A.new 7,8
puts a.a1 # -> 7
puts a.a2 # -> 8

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?

Ashley Moran

10/13/2007 6:16:00 PM

0


On Oct 13, 2007, at 5:00 pm, Trans wrote:

> class C
> attr_reader *initializes_with(:x, :y, :z)
> end

Very clever :)


--
blog @ http://aviewfro...
linked-in @ http://www.linkedin.com/in/a...
currently @ home



Erik Veenstra

10/13/2007 8:02:00 PM

0

It can be as simple as this.

gegroet,
Erik V. - http://www.erikve...

----------------------------------------------------------------

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 Foo
generate_initialize :a, :b, :c
end

p Foo.new(1, 2, 3)

----------------------------------------------------------------


Brian Adkins

10/13/2007 8:14:00 PM

0

On Oct 13, 4:01 pm, Erik Veenstra <erikv...@gmail.com> wrote:
> It can be as simple as this.
>
> gegroet,
> Erik V. -http://www.erikve...
>
> ----------------------------------------------------------------
>
> 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 Foo
> generate_initialize :a, :b, :c
> end
>
> p Foo.new(1, 2, 3)

Might as well define the attrs while you're at it so you can get the
data out :)

arcadio

10/31/2007 8:08:00 PM

0

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.

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

Trans

10/31/2007 8:34:00 PM

0



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.

T.