2012-02-13 3 views
2

Объекты MyClass имеют переменные экземпляра a, b и c (простите мои неопределенные абстракции). Кроме того, при написании этих классов я хочу иметь возможность устанавливать a, b и c, но я не хочу, чтобы мои пользователи имели возможность.Ruby: Создание экземпляров экземпляров из методов класса

class MyClass 
    attr_accessor :a, :b, :c 
    private :a=, :b=, :c= 
end 

Я хотел MyClass, чтобы быть создан с помощью любого из 2-х способов, таких, что я хотел бы быть в состоянии назвать следующие:

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=, потому что я не хочу, чтобы мои пользователи меняли этот материал. (Это нарушит мой пример в реальном мире). Однако, опять же, я являюсь пользователем при определении метода класса.

Итак, это то, с чем я работаю. Как я могу создать экземпляры «ограничительного» класса в методах класса?

ответ

4

Вы были немного запутаны, вы можете сделать это немного проще.

class MyClass 
    attr_reader :a, :b, :c 

    private_class_method :new 

    def initialize(a,b) 
    @a = a 
    @b = b 
    end 

    def self.create_from_foo foo_data 
    #some parsing of foo_data and computation of a, b, and c 
    myclass = new(a,b) 
    #... 
    end 

    def self.create_from_bar bar_data 
    #again, computation of bar_data 
    myclass = new(a,b) 
    #... 
    end 
end 
+0

Чистое и ясное! Благодаря! –

3

Вполне можно вызвать частные методы класса из других методов класса. Однако в Ruby вы не можете вызывать частные методы (отличные от сеттеров) с явным приемником.

Так что, если вы просто напишете new вместо MyClass.new, он будет работать нормально.