2014-11-30 20 views
5

Tôi đang theo dõi khóa học Ruby của Codecademy, khoảng 85% đã hoàn thành.Phím tắt để gán các biến mẫu

Lặp đi lặp lại nó sẽ yêu cầu bạn tạo ra một lớp và vượt qua trong một số thông số và làm cho họ biến Ví dụ, như thế này ví dụ:

class Computer 
    def initialize(username, password) 
     @username = username 
     @password = password 
    end 
end 

Mỗi lần, nó sẽ yêu cầu bạn thực hiện các biến cùng một ví dụ chính xác như các thông số bạn đã nhập.

Điều đó làm tôi băn khoăn liệu có cách nào Ruby tự động xử lý việc này hay không, loại bỏ sự cần thiết phải tự mình loại bỏ mọi lúc.

Tôi biết bạn có thể làm

class Computer 
    def initialize(username, password) 
     @username, @password = username, password 
    end 
end 

nhưng đó là hầu như không ít gõ.

tôi đã làm một số tìm kiếm và phát hiện ra rằng bạn có thể tạo một bộ 'thu khí' sử dụng attr_reader như

class Song 
    attr_reader :name, :artist, :duration 
end 

aSong = Song.new("Bicylops", "Fleck", 260) 
aSong.artist # "Fleck" 
aSong.name # "Bicylops" 
aSong.duration # 260 

Nhưng như xa như tôi có thể nói đó không phải là thực sự những gì tôi đang tìm kiếm. Tôi không cố gắng tự động tạo getters và/hoặc setters. Những gì tôi đang tìm kiếm sẽ là một cái gì đó như thế này

class Person 
    def initialize(name, age, address, dob) #etc 
     # assign all passed in parameters to equally named instance variables 
     # for example 
     assign_all_parameters_to_instance 
     # name, age, address and dob would now be accessible via 
     # @name, @age, @address and @dob, respectively 
    end 
end 

tôi đã làm một số tìm kiếm cho shortcut ruby ​​cho gán biến dụ và giống nhau nhưng không thể tìm thấy câu trả lời.

Điều này có khả thi không? Nếu vậy, làm thế nào?

Trả lời

6
Person = Struct.new(:name, :artist, :duration) do 
    # more code to the Person class 
end 

tùy chọn khác của bạn là phải vượt qua một Hash/từ khóa của các biến thay vào đó và sử dụng giống như ActiveModel :: Mẫu https://github.com/rails/rails/blob/master/activemodel/lib/active_model/model.rb#L78-L81

def initialize(params={}) 
    params.each do |attr, value| 
    self.instance_variable_set("@#{attr}", value) 
    end if params 
end 
+0

Có bất kỳ hạn chế trong việc sử dụng một cấu trúc thay vì một lớp học? Nó có vẻ hữu ích, nhưng tôi hy vọng nó có một nhược điểm: -P –

+0

Rút ra là một Struct là khoan dung hơn để đối số kích thước 'Person.new (" John ")' -> không có lỗi, nghệ sĩ và thời gian thiết lập để nil . Thông tin thêm về các cấu trúc bạn có thể tìm thấy ở đây: http://www.ruby-doc.org/core-2.1.5/Struct.html – avlazarov

+0

Giống như Proc và lambda sau đó. Cảm ơn, điều này là hữu ích –

1

Trước hết, khối thứ hai của bạn với bộ attr_reader sẽ không công việc. Vì bạn đang cung cấp 3 đối số cho phương thức mặc định initialize, chấp nhận 0 đối số.

Trả lời cho câu hỏi của bạn là không, không có phương pháp như vậy, trừ khi bạn định tự mình định nghĩa bằng cách sử dụng lập trình meta.

+0

Tôi tìm thấy attr_reader [ở đây] (http://phrogz.net/programmingruby/tut_classes.html), nó không phải là mã của tôi. Nhưng cảm ơn bạn đã chỉ ra rằng –

+0

@TimCastelijns Tôi cho rằng họ chỉ bỏ qua phương thức 'initialize' được định nghĩa ở đầu bài viết trong các ví dụ sau. –

+0

Ah tôi hiểu rồi. Điều đó làm cho toàn bộ khái niệm không sử dụng được. –

1

assign_all_parameters_to_instance không thể tồn tại theo cách bạn muốn. Nó sẽ cần phải có quyền truy cập vào các biến địa phương của người gọi hoặc các thông số, đó là một điều rất khó xử để làm, và vi phạm một phương pháp đóng gói.

Tuy nhiên, bạn chỉ có thể tạo ra một initialize phương pháp thích hợp:

class Module 
    private def trivial_initializer(*args) 
    module_eval(<<-"HERE") 
     def initialize(#{args.join(', ')}) 
     #{args.map {|arg| "@#{arg} = #{arg}" }.join("\n")} 
     end 
    HERE 
    end 
end 

class Computer 
    trivial_initializer :username, :password 
end 

Computer.new('jwm', '$ecret') 
# => #<Computer:0x007fb3130a6f18 @username="jwm", @password="$ecret"> 
+0

* Nó sẽ cần phải có quyền truy cập vào các biến địa phương của người gọi hoặc các thông số, đó là một điều rất khó xử để làm, và vi phạm một phương pháp đóng gói. * Biết rằng tôi không phải làm những gì tôi đang cố gắng làm (và tại sao) là thông tin giá trị, cảm ơn –

Các vấn đề liên quan