Project

General

Profile

Feature #14025

#initialize with ivars

Added by frankpimenta (Frank Pimenta) almost 2 years ago. Updated almost 2 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:83338]

Description

For:

class Person
def initialize name = 'person'
@name = name
end
end

I thought that the following would be nice:

class Person
initialize :name
end

class Person
initialize name: 'person', age: 18
end

class Person
def initialize @name="person", @age=18
puts "initializing...something to run before"
end
end

--
B., Frank.

History

#1

Updated by frankpimenta (Frank Pimenta) almost 2 years ago

  • Backport deleted (2.3: UNKNOWN, 2.4: UNKNOWN)
  • Tracker changed from Bug to Feature

Updated by frankpimenta (Frank Pimenta) almost 2 years ago

 module ObjectInitialization
    def self.included base
       base.class_eval do
         extend ClassMethods
       end
    end
    module ClassMethods
      def attr_initializer default_arguments={}
         raise RuntimeError.new "No args provided to ::init" if default_arguments.empty?

         @@__default_arguments__ = default_arguments

         class_eval do
           define_method :initialize do |args=nil|
             arguments = args.nil? ? @@__default_arguments__ :  @@__default_arguments__.merge(args)
             arguments.each_pair do |name, value|
               instance_variable_set "@#{name.to_s}", value
             end
           end
         end
      end
    end
  end

  class Object
    include ObjectInitialization
  end

  class Person
    attr_initializer name: 'person', age: 18, address: "somewhere"
  end

  p0 = Person.new
  p1 = Person.new name: "frank"
  p2 = Person.new name: "adam", profession: "developer"

Updated by shevegen (Robert A. Heiler) almost 2 years ago

I don't quite understand your second example.

class Person
  initialize name: 'person', age: 18

Did you not define before that only one argument can be passed?

class Person
  def initialize name = 'person'

By the way, I seem to be missing parts of what you are trying to
suggest.

If you mean to initialize @variables by default, similar to what
crystal does, then I think this has been suggested before. I do
not know of the current status either way, but I think that it
may be for ruby 3.x at best due to backwards compatibility (I may
be wrong here too but the ruby core team has said this a few
times before in general).

Updated by frankpimenta (Frank Pimenta) almost 2 years ago

Where did I define that only one argument could be passed?

I don't want to initialize ivar explicitly in #initialize.

I would like that instead of:

def initialize name='default_name', age=0
@name, @age = name, age
end

I could do either:

def initialize @name = 'default_name', @age=0
end

or as with getter and setters via attr_* :

initialize name: 'default_name', age: 0

What parts do you think are missing? Maybe I already know them but I am trying to find time to fulfil it.

Also available in: Atom PDF