Generation of initialize

Discussion in 'Ruby' started by arcadiorubiogarcia@gmail.com, Oct 13, 2007.

  1. Guest

    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.
    , Oct 13, 2007
    #1
    1. Advertising

  2. Trans Guest

    On Oct 13, 5:20 am, 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)
    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.
    Trans, Oct 13, 2007
    #2
    1. Advertising

  3. Ashley Moran Guest

    On Oct 13, 2007, at 1:20 pm, 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://aviewfromafar.net/
    linked-in @ http://www.linkedin.com/in/ashleymoran
    currently @ home
    Ashley Moran, Oct 13, 2007
    #3
  4. Guest

    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.
    , Oct 13, 2007
    #4
  5. Trans Guest

    On Oct 13, 7:55 am, 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.
    Trans, Oct 13, 2007
    #5
  6. Brian Adkins Guest

    On Oct 13, 8:19 am, 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?
    Brian Adkins, Oct 13, 2007
    #6
  7. Ashley Moran Guest

    Ashley Moran, Oct 13, 2007
    #7
  8. It can be as simple as this.

    gegroet,
    Erik V. - http://www.erikveen.dds.nl/

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

    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)

    ----------------------------------------------------------------
    Erik Veenstra, Oct 13, 2007
    #8
  9. Brian Adkins Guest

    On Oct 13, 4:01 pm, Erik Veenstra <> wrote:
    > It can be as simple as this.
    >
    > gegroet,
    > Erik V. -http://www.erikveen.dds.nl/
    >
    > ----------------------------------------------------------------
    >
    > 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 :)
    Brian Adkins, Oct 13, 2007
    #9
  10. Guest

    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
    , Oct 31, 2007
    #10
  11. Trans Guest

    On Oct 31, 4:10 pm, 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.
    Trans, Oct 31, 2007
    #11
  12. Trans wrote:
    >
    > On Oct 31, 4:10 pm, 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
    Joel VanderWerf, Oct 31, 2007
    #12
  13. Guest

    Thanks. It was the "()" on super.

    On 31 oct, 21:53, Joel VanderWerf <> wrote:
    > Trans wrote:
    >
    > > On Oct 31, 4:10 pm, 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
    , Oct 31, 2007
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Madhu
    Replies:
    7
    Views:
    27,468
    dfriedman
    May 28, 2008
  2. Daniel Koethe

    initialize memory units

    Daniel Koethe, Nov 8, 2004, in forum: VHDL
    Replies:
    1
    Views:
    791
    mike_treseler
    Nov 8, 2004
  3. Brandon
    Replies:
    5
    Views:
    5,914
    Mike Treseler
    Sep 29, 2005
  4. Pasacco
    Replies:
    5
    Views:
    3,660
    Thomas Stanka
    Jan 9, 2006
  5. John W. Long

    HTML Generation (Next Generation CGI)

    John W. Long, Nov 22, 2003, in forum: Ruby
    Replies:
    4
    Views:
    327
    John W. Long
    Nov 24, 2003
Loading...

Share This Page