Trước hết, một phần lý do mã ví dụ của bạn không làm việc cho bạn là bạn có hai @people
biến khác nhau - một là một dụ biến và người kia là một trường hợp lớp biến.
class Example
# we're in the context of the Example class, so
# instance variables used here belong to the actual class object,
# not instances of that class
self.class #=> Class
self == Example #=> true
@iv = "I'm a class instance variable"
def initialize
# within instance methods, we're in the context
# of an _instance_ of the Example class, so
# instance variables used here belong to that instance.
self.class #=> Example
self == Example #=> false
@iv = "I'm an instance variable"
end
def iv
# another instance method uses the context of the instance
@iv #=> "I'm an instance variable"
end
def self.iv
# a class method, uses the context of the class
@iv #=> "I'm a class instance variable"
end
end
Nếu bạn muốn tạo biến một lần trong một lớp học để sử dụng trong các phương pháp thể hiện của lớp đó, sử dụng constants
hoặc class variables
.
class Example
# ruby constants start with a capital letter. Ruby prints warnings if you
# try to assign a different object to an already-defined constant
CONSTANT_VARIABLE = "i'm a constant"
# though it's legit to modify the current object
CONSTANT_VARIABLE.capitalize!
CONSTANT_VARIABLE #=> "I'm a constant"
# class variables start with a @@
@@class_variable = "I'm a class variable"
def c_and_c
[ @@class_variable, CONSTANT_VARIABLE ] #=> [ "I'm a class variable", "I'm a constant" ]
end
end
Mặc dù vậy, trong ngữ cảnh của bạn, bạn có thể không muốn tất cả các trường hợp của bạn Family_Type1 đề cập đến cùng một cảnh sát và kế toán phải không? Hay bạn?
Nếu chúng ta chuyển sang sử dụng các biến lớp:
class Family_Type1
# since we're initializing @@people one time, that means
# all the Family_Type1 objects will share the same people
@@people = [ Policeman.new('Peter', 0), Accountant.new('Paul', 0), Policeman.new('Mary', 0) ]
def initialize(*ages)
@@people.zip(ages).each { |person, age| person.age = age }
end
# just an accessor method
def [](person_index)
@@people[person_index]
end
end
fam = Family_Type1.new(12, 13, 14)
fam[0].age == 12 #=> true
# this can lead to unexpected side-effects
fam2 = Family_Type1.new(31, 32, 29)
fam[0].age == 12 #=> false
fam2[0].age == 31 #=> true
fam[0].age == 31 #=> true
Việc khởi chạy, có thể thực hiện với lập trình meta, như Chirantan nói, nhưng nếu bạn chỉ khởi tạo một vài lớp học, và bạn biết những gì tên của họ là, bạn cũng có thể làm điều đó chỉ bằng cách sử dụng bất cứ điều gì bạn đọc từ tệp:
PARAMS = File.read('params.csv').split("\n").map { |line| line.split(',') }
make_people = proc do |klasses, params|
klasses.zip(params).map { |klass,name| klass.new(name, 0) }
end
class Example0
@@people = make_people([ Fireman, Accountant, Fireman ], PARAMS[0])
end
class Example1
@@people = make_people([ Butcher, Baker, Candlestickmaker ], PARAMS[0])
end
Đây là câu trả lời duy nhất thực sự giải thích toàn bộ tình huống IMO. – Chuck
giải thích tuyệt vời, giúp xóa các khái niệm ... thnks –