How to create an object in Ruby without using new ones

You can create a complex number in Ruby with

c = Complex.new(1,2)

but it can be reduced to

c = Complex(1,2)

Is it possible to achieve the same functionality without having to define a function outside the class, as in the example below?

class Bits
  def initialize(bits)
    @bits = bits
  end
end

def Bits(list) # I would like to define this function inside the class
  Bits.new list
end

b = Bits([0,1])

I think Ruby should allow at least one of the suggested constructors below

class Bits
  def initialize(bits)
    @bits = bits
  end

  def self.Bits(list) # version 1
    new list
  end

  def Bits(list)      # version 2
    new list
  end

  def Bits.Bits(list) # version 3
    new list
  end
end
+4
source share
4 answers

Enter this snippet:

def make_light_constructor(klass)
    eval("def #{klass}(*args) #{klass}.new(*args) end")
end

Now you can do this:

class Test
    make_light_constructor(Test)
    def initialize(x,y)
        print x + y
    end 
end

t = Test(5,3)

Yes, I know that you are still defining a function outside the class, but this is only one function, and now any class you want can use its implementation instead of doing one function for each class.

+3
source
c = Complex(1,2)

+4

- () Ruby ( C).

- , []:

class Bits
  def self.[](list)
    Bits.new list
  end
end

- :

b = Bits[[1,2]]
+2

- , 2 :

  • self.included - , include Mod
  • self.extend - , extend Mod

, self.included.

: . , ; .
: Complex(2,3) ( [] (), fooobar.com/questions/1545547/...); initialize, self.included .

module M1
  # some random classes
  class A; end 
  class B
    def initialize list
        @list = list
    end
    attr_accessor :list
  end
  class C
    def initialize var1
        @var1 = var1
    end
    attr_accessor :var1
  end
  Answer = 42
  # called on `include module_name`
  def self.included mod
    # classes are constants (in normal cases)
    constants.each do |cons| 
      class_eval do
        # I don't like hard-coded `::M1`
        klass = ::M1.const_get cons
        if klass.class==Class 
            define_method cons do |*args, &block|
              klass.new *args, &block 
            end
        end
      end
    end
  end
end

include M1


p A()

b = B([1,2,3])
p b.list

c = C 42
p c.var1

puts Answer() 
# NoMethodError: undefined method `Answer' for main:Object
# thats good, because Answer is not a class!
+1

Source: https://habr.com/ru/post/1545547/


All Articles