mich damit anfangen Lassen du solltest nicht. Es ist sehr schwierig, die Benutzer dazu zu zwingen, das zu tun, was sie tun möchten, auch wenn es keine öffentliche Schnittstelle ist. Ein mehr idiomatischer Ansatz würde es deutlicher machen, dass es nicht Teil der öffentlichen Schnittstelle ist. Sie können das tun, um die Klasse, indem sie private:
class RegexMockery
class MatchDataMockery
def initialize(whatever)
puts "I'm being created #{whatever}"
end
def [](_)
'42'
end
end
private_constant :MatchDataMockery
def match(string)
MatchDataMockery.new(string)
end
end
match_result = RegexMockery.new.match('foo')
# I'm being created foo
# => #<RegexMockery::MatchDataMockery:0x007fe990de2ed0>
match_result[0] # => '42'
RegexMockery::MatchDataMockery # !> NameError: private constant RegexMockery::MatchDataMockery referenced
Aber wenn man auf die Menschen darauf bestehen, hassen Sie, speichern Sie die Methode, undef es und es nennen, wenn Sie Instanzen erstellen möchten:
class Foo
def initialize(whatever)
puts "Now you see me #{whatever}"
end
def brag
puts "I can create Foos and you can't!!!1!!"
end
end
class Bar
foos_new = Foo.method(:new)
Foo.singleton_class.send :undef_method, :new
define_method(:sorcery) do
foos_new.call('bar').brag
end
end
Bar.new.sorcery
# Now you see me bar
# I can create Foos and you can't!!!1!!
Foo.new # !> NoMethodError: undefined method `new' for Foo:Class
Viele von Kernklassen brechen die Regeln aus verschiedenen Gründen. Manchmal ist es ziemlich peinlich, dass sie sich besonders bemüht haben, etwas Besonderes zu sein. – tadman
@tadman die Regeln brechen? – Stefan
Wissen Sie, Objekte, die nicht initialisiert werden können, sind im Grunde magische Nebenprodukte anderer Prozesse. Wie Fixnum ist es nicht etwas, das man "Fixnum.new" nennen kann, weil Integer intern eigentlich nur Objekte sind. – tadman