How to Make the Class Constructor Private in Ruby

How to make the class constructor private in Ruby?

Try this:

class A
private_class_method :new
end

More on APIDock

Ruby class initialize (constructor) is private method or public method?

Let's see:

class Test
def initialize; end
end

p Test.new.private_methods.sort.include?(:initialize)

This prints true, so initialize is a private method. This makes sense, it is only called by the new class method if the object is created. If we want, we can do something like this:

class Test
def initialize
@counter = 0
end

def reset!
initialize
end
end

Misusing the constructor like this could however lead to problems if it does more than simple variable initialization.

Want to instantiate a ruby class using a private constructor from factory

Update: Answer

Including this module in my class, protects Klass.new from being called:

module ProtectedConstructor
def self.included(klass)
klass.module_eval do
class << self
protected :new

def inherited(klass)
klass.module_eval do
def self.new(*args); super; end
end
end
end
end
end
end

Instantiating Klass via protected constructor, takes place as such:

Klass.send(:new, *params...*)

Credit for this solution can be found: here

Have a different public constructor than a private one

I guess this would do what you expect.

class C
def initialize(x, y = 0)
@x = x
@y = y
end

def self.with_position
new(3, 4)
end
end

c1 = C.new(5)
c2 = C.with_position

If you want to prohibit setting y by anyone from outside the class, you can use some private method behind the scenes (as you suggested) and konstructor gem

class C
def initialize(x)
set_coords(x, 0)
end

konstructor
def with_position
set_coords(3, 4)
end

private

def set_coords(x, y)
@x = x
@y = y
end
end

c1 = C.new(5)
c2 = C.with_position

hide ruby's constructor from outsiders but use it inside instance methods

did you try to use send?

SomeClass.send :new, @hash.merge({a => b})

How do I make a class whose constructor looks like the constructor of a built-in class?

class Dog
def initialize(name)
@name = name
end

def greet
puts 'hello'
end
end

def Dog(x)
Dog.new(x) #Create a new instance of the Dog class and return it.
end

d = Dog("Rover")
d.greet

--output:--
hello

Ruby factory method to call private setter

This is possible only with a hacky approach:

class Foo
def self.from_bar(bar)
new(bar.foo_id).tap { |f| f.send(:bar=, bar) }
# or, better:
new(bar.foo_id).tap { |f| f.instance_variable_set(:@bar, bar) }
end

private
attr_accessor :bar
end

Honestly, making attr_accessor private makes a little sense, though.



Related Topics



Leave a reply



Submit