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
What's the Right Way to Implement Equality in Ruby
Undefined Method 'Devise' for User
How to Initialize an Array Inside a Hash in Ruby
Getting Rails Url Helpers to Automatically Output Https Urls
What Is Catch and Throw Used for in Ruby
What Is the Argument Against Using Before, Let and Subject in Rspec Tests
Parsing Atom & Rss in Ruby/Rails
How to Get Url of Active Storage Image
Ruby on Rails: Permission Denied When Using "Rails Generate Controller Welcome"
How Get All Routes in My Rails Application
How Many Rails Apps on 1 Heroku Dyno
Packaging Ruby into a Portable Executable
How to Flatten an Array of Arrays - But Not All the Way Down
Converting Upper-Case String into Title-Case Using Ruby
Bundler Install Getting "I18N Requires Ruby Version >= 1.9.3"