Đây là những gì tôi sử dụng (tôi gọi đây là thành ngữ băm-init).
def initialize(object_attribute_hash = {})
object_attribute_hash.map { |(k, v)| send("#{k}=", v) }
end
Nếu bạn đang ở trên của Ruby 1.9 bạn có thể làm điều đó thậm chí sạch hơn (gửi cho phép các phương pháp tư nhân):
def initialize(object_attribute_hash = {})
object_attribute_hash.map { |(k, v)| public_send("#{k}=", v) }
end
này sẽ nâng cao một NoMethodError nếu bạn cố gắng để gán cho foo và phương pháp "foo = " không tồn tại. Nếu bạn muốn làm cho nó sạch sẽ (gán attrs mà tác giả tồn tại), bạn nên làm một tấm séc
def initialize(object_attribute_hash = {})
object_attribute_hash.map do |(k, v)|
writer_m = "#{k}="
send(writer_m, v) if respond_to?(writer_m) }
end
end
tuy nhiên điều này có thể dẫn đến tình huống mà bạn nuôi đối tượng phím sai của bạn (ví dụ từ một hình thức) và thay vì thất bại lớn tiếng nó sẽ nuốt chửng chúng - gỡ lỗi đau đớn phía trước. Vì vậy, trong cuốn sách của tôi, NoMethodError là một lựa chọn tốt hơn (nó có nghĩa là vi phạm hợp đồng).
Nếu bạn chỉ muốn một danh sách của tất cả các nhà văn (không có cách nào để làm điều đó cho độc giả) bạn làm
some_object.methods.grep(/\w=$/)
đó là "nhận được một loạt các tên phương pháp và grep nó cho các mục mà cuối với một dấu bằng đơn sau ký tự từ ".
Nếu bạn làm
eval("@#{opt} = \"#{val}\"")
và val xuất phát từ một mẫu web - xin chúc mừng, bạn chỉ cần trang bị ứng dụng của bạn với một rộng mở khai thác.
Đã cập nhật để sử dụng Array # concat thay vì Array # << để tạo mảng phẳng. – tadman
Ý tưởng tuyệt vời! Sẽ giữ cái này trong thư viện ở đâu đó, tôi chắc rằng nó sẽ rất tiện dụng! –