Объекты MyClass имеют переменные экземпляра a, b и c (простите за мои смутные абстракции).Кроме того, при написании этих классов я хочу установить a
, b
и c
, но я не хочу, чтобы мои пользователи могли.
class MyClass
attr_accessor :a, :b, :c
private :a=, :b=, :c=
end
Iхотел бы, чтобы MyClass создавался одним из двух способов, так что я хотел бы иметь возможность вызывать следующее:
f = MyClass.create_from_foo foo_data
b = MyClass.create_from_bar bar_data
и получать экземпляры MyClass в f
и b
.f
и b
неразличимы после создания экземпляра, но, конечно, были созданы по-разному.После этих вызовов и f
, и b
имеют a
, b
и c
.
. Я бы не хотел, чтобы MyClass создавался через new
.Поскольку оба этих способа создания одинаково действительны, я чувствую, что «предпочитаю» foo_data, а не bar_data, или наоборот, я бы не хотел этого делать.Поэтому я чувствую, что должен приватизировать new
и разрешить создание экземпляров MyClass этими методами класса, чтобы попытаться выровнять игровое поле.Другими словами, я пытаюсь избежать этого:
#don't want this
f = MyClass.new foo_data
b = MyClass.create_from_bar bar_data #not quite "fair" to bar_data
Итак, позвольте мне начать писать эти create_from_<type>
методы класса:
class MyClass
#from earlier
attr_accessor :a, :b, :c
private :a=, :b=, :c=
private_class_method :new
def MyClass.create_from_foo foo_data
#some parsing of foo_data and computation of a, b, and c
myclass = MyClass.new
myclass.a = a
myclass.b = b
#...
end
def MyClass.create_from_bar bar_data
#again, computation of bar_data
myclass.a = a
myclass.b = b
#...
end
end
Теперь, если вы следите за мной, вы заметите, что я не могу этого сделать!Я заблокировал себя!
- Я приватизировал
new
, потому что я не хотел, чтобы мои пользователи создавали объекты MyClass таким способом.Я хочу, чтобы они использовали методы класса.А в пространстве определения метода класса я в основном пользователь. - Я приватизировал
a=
, b=
и c=
, потому что я не хочу, чтобы мои пользователи меняли это.(Это сломало бы мой пример из реального мира).Опять же, однако, я пользователь при определении метода класса.
Итак, с этим я и работаю.Как я могу создать экземпляры «ограничительного» класса в методах класса?