Ruby có thể là điều đáng sợ đơn giản đôi khi. Không có vòng lặp!
class Weekend < Struct.new(:start_date, :end_date, :title, :description, :location)
# params: Hash with symbols as keys
def initialize(params)
# arg splatting to the rescue
super(* params.values_at(* self.class.members))
end
end
Lưu ý rằng bạn thậm chí không cần phải sử dụng kế thừa - một mới Struct
thể được tùy chỉnh trong quá trình tạo:
Weekend = Struct.new(:start_date, :end_date, :title, :description, :location) do
def initialize(params)
# same as above
end
end
Test:
weekend = Weekend.new(
:start_date => 'start_date value',
:end_date => 'end_date value',
:title => 'title value',
:description => 'description value',
:location => 'location value'
)
p [:start_date , weekend.start_date ]
p [:end_date , weekend.end_date ]
p [:title , weekend.title ]
p [:description, weekend.description ]
p [:location , weekend.location ]
Lưu ý rằng đây không thực sự đặt các biến mẫu. Bạn lớp học sẽ có getters opaque và setters. Nếu bạn không muốn phơi bày chúng, bạn có thể quấn thêm một lớp khác xung quanh nó. Dưới đây là một ví dụ:
# this gives you more control over readers/writers
require 'forwardable'
class Weekend
MyStruct = ::Struct.new(:start_date, :end_date, :title, :description, :location)
extend Forwardable
# only set up readers
def_delegators :@struct, *MyStruct.members
# params: Hash with symbols as keys
def initialize(params)
# arg splatting to the rescue
@struct = MyStruct.new(* params.values_at(* MyStruct.members))
end
end
Tôi ghét trả lời từ iphone và xem đánh dấu hư hỏng ... – apneadiving
Tôi hiểu mong muốn tránh metaprog không cần thiết, nhưng điều này không thực sự là mã ngắn gọn mà OP yêu cầu. Bạn phải chỉ định thủ công từng tên trường. – Kelvin