2012-03-22 23 views
7

Tôi không thể hình dung ra khối thích hợp khởiLàm thế nào để khởi tạo lớp trong khối trong Ruby?

class Foo 
    attr_accessor :bar 
end 

obj = Foo.new do |a| 
    a.bar = "baz" 
end 

puts obj.bar 

Expect "baz" thay vì có được con số không

câu thần chú thích cho initializers lớp khối trong ruby ​​là gì?

+0

'attr_accessor' không thể hoạt động ở dạng đó và khối không bao giờ được gọi. –

+0

Cảm ơn, bạn đã đúng về điều đó, tôi đã sửa nó để mã "chức năng" bây giờ là – Doug

+0

Phải, tôi hiểu rằng nó không được gọi (điều này giải thích tại sao nó không hoạt động). Tôi thích ý tưởng "nhấn" bên dưới, vì nó cho phép tôi sử dụng các công cụ như FactoryGirl (yêu cầu trình khởi tạo mặc định) mà không phải ghi đè lên mới. – Doug

Trả lời

9

Thử lại:

class Foo 
    attr_accessor :bar 
end 

obj = Foo.new.tap do |a| 
    a.bar = "baz" 
end 

puts obj.bar 
+0

Điều đó không giống nhau. Ngoài ra, nó sẽ tăng một 'NameError'. –

+0

Đó là cách tốt nhất mà không cần thêm những cách mới mà người dùng của bạn phải đọc tài liệu. – Reactormonk

+0

Điều đó tôi đồng ý. –

2

Tôi không nghĩ rằng new có thể mất một khối. Không bao giờ thấy nó ở bất cứ đâu. Tại sao bạn muốn khởi tạo trong một khối? Bạn luôn có thể làm obj = foo.new.tap do |a| ... Nếu bạn thực sự muốn có một khối

+0

Nó không phải là nó * không thể * lấy một khối, nó chỉ là xấu xí. Mặc dù vậy, đó là một "thành ngữ" thường thấy. –

+0

Ồ, được rồi. Tôi đã học được điều gì đó ngày hôm nay – ksol

+0

Tại sao nó xấu xí? Đó là một thành ngữ phổ biến trong các ngôn ngữ khác mà tôi đã sử dụng như C#. – Doug

0

thực sự bạn có một constructor cho các mục đích:

class Foo 
    attr_accessor :bar 

    def initialize(bar = "baz") 
    @bar = bar 
    end 

end 
+0

Có thể bạn thực sự nên tạo một tham số đó. –

+0

Niklas, vâng, điều đó sẽ tốt hơn – Sergey

+0

Nó không phổ biến vượt qua chúng như là constrcuter. Chỉ cần nhìn vào một số mã ruby ​​trong github – slashmili

29

Một cách khác để thực hiện một khởi tạo khối sẽ là tự viết cho mình một:

class Foo 
    attr_accessor :bar 

    def initialize 
    yield self if block_given? 
    end 
end 

Và sau đó sử dụng nó:

foo = Foo.new do |f| 
    f.bar = true 
end 

hai xu của tôi.

+0

không có nghi ngờ đây là cách tốt hơn để khởi tạo một lớp học với một khối. –

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