2011-01-07 28 views
17

tuyên bố từ chối trách nhiệm: Mã được lấy từ ruby koansRuby: phạm vi rõ ràng trên định nghĩa lớp

Đây là từ một cuộc thảo luận về hằng số phạm vi trong các lớp. Đây là defintion của một cặp vợ chồng vài lớp:

class Animal 
    LEGS = 4 
    def legs_in_animal 
    LEGS 
    end 
end 

class MyAnimals 
    LEGS = 2 

    class Bird < Animal 
    def legs_in_bird 
     LEGS 
    end 
    end 
end 

Tại thời điểm này làm MyAnimals::Bird.new.legs_in_bird kết quả trong 2 và tôi hiểu tại sao - tìm kiếm không gian từ vựng cho hằng số trước khi hệ thống cấp bậc thừa kế.

Sau đó, lớp này được định nghĩa:

class MyAnimals::Oyster < Animal 
    def legs_in_oyster 
    LEGS 
    end 
end 

Các hướng dẫn nói rằng bây giờ gọi MyAnimals::Oyster.new.legs_in_oyster kết quả trong 4 và tôi không thể hình dung nó ra. Nó xuất hiện với tôi rằng Oyster là một lớp lồng nhau trong MyAnimals và như vậy tôi mong đợi nó để hành xử theo cùng một cách như lớp chim đã làm ở trên. Tôi đang thiếu một số thông tin quan trọng về những gì tuyên bố lớp Oyster với phương tiện phạm vi rõ ràng.

bất cứ ai có thể giải thích điều này cho tôi không? Tôi đã tìm thấy hàng trăm hướng dẫn về lớp học ruby ​​qua Google nhưng không có ai trong số họ giải quyết tình huống này.

cảm ơn bạn trước ...

+3

Có. Có. BỐN. Chân!!! zetetic

+0

Bốn chân tốt, hai chân xấu

+3

Có ai viết mã phụ thuộc vào hằng số nào sẽ đạt được trước không? –

Trả lời

17

Tôi nghĩ rằng this example giải thích tốt nhất.Ruby tìm kiếm định nghĩa liên tục theo thứ tự này:

  1. Phạm vi kèm theo
  2. Bất kỳ phạm vi bên ngoài (lặp lại cho đến khi cấp cao nhất đạt được) Bất kỳ phạm vi bên ngoài (lên đến nhưng không bao gồm cấp cao nhất
  3. module bao gồm
  4. lớp cha (es)
  5. Lên trên mức
  6. Object
  7. .210
  8. Kernel

EDIT

Nhờ Mark Amery để chỉ ra lỗi này. Cấp cao nhất chỉ đạt được trong trường hợp không có phạm vi kèm theo và/hoặc siêu lớp. Ví dụ liên kết thực sự làm cho điều này rõ ràng, thật đáng buồn tôi đã đọc sai.

Một ví dụ cho trường hợp này:

FOO = 'I pity the foo!' 

module One 
    FOO = 'one' 

    class Two 
    FOO = 'two' 

    def self.foo 
     FOO 
    end 
    end 

    class Three < Two 
    def self.foo 
     FOO 
    end 
    end 
end 

class Four 
    class Five < Four 
    def self.foo 
     FOO 
    end 
    end 
end 

describe FOO do 
    it "depends where it is defined" do 
    expect(FOO).to eq 'I pity the foo!' # top-level 
    expect(One::FOO).to eq 'one' # module 
    expect(One::Two.foo).to eq 'two' # class 
    expect(One::Three.foo).to eq 'one' # outer scope (One) comes before superclass 
    expect(Four::Five.foo).to eq 'I pity the foo!' # top-level 
    end 
end 
+0

Điều gì cấu thành 'cấp cao nhất'? Nếu tôi làm 'FOO = 'topoffile'; Kiểm tra lớp học; FOO = 'insuperclass'; kết thúc; lớp Test2

+0

@MarkAmery bắt tốt. – zetetic

5

Nếu bạn xác định Oyster INSIDE định nghĩa MyAnimals lớp, sau đó bạn sẽ có được câu trả lời rằng legs_in_oyster là 2.

Nếu bạn xác định Oyster riêng - đó là , bạn xác định nó sau khi LEGS = 2 đã vượt qua phạm vi, bạn nhận được phản hồi của 4.

Điều này cho thấy rằng lớp lồng nhau hoạt động khác với không gian tên, có lẽ giống như đóng.

--- EDIT ---

irb(main):076:0> class MyAnimals::RunningRoach < Animal; def using_legs; LEGS; end; end 
=> nil 
irb(main):077:0> MyAnimals::RunningRoach.new.kind_of?(MyAnimals) 
=> false 
irb(main):078:0> MyAnimals::RunningRoach.new.kind_of?(Animal) 
=> true 
irb(main):081:0> class MyAnimals::Mantis < MyAnimals; def killing_legs; LEGS; end; end 
=> nil 
irb(main):082:0> MyAnimals::Mantis.new.kind_of?(Animal) 
=> false 
irb(main):083:0> MyAnimals::Mantis.new.kind_of?(MyAnimals) 
=> true 
irb(main):084:0> MyAnimals::Mantis.new.killing_legs 
=> 2 
irb(main):085:0> MyAnimals::RunningRoach.new.using_legs 
=> 4 

Theo "The Ruby Ngôn ngữ lập trình", hằng đang nhìn lên trong phạm vi từ vựng trong những nơi mà chúng được sử dụng đầu tiên, và trong hệ thống phân cấp thừa kế thứ hai . Vậy phạm vi từ vựng của thứ gì đó thừa hưởng Động vật là gì? Động vật chính nó, phải không? Lớp MyAnimals định nghĩa lại LEGS, vì vậy mọi thứ sử dụng LEGS và được xác định là bên trong MyAnimals, trước tiên sẽ tìm LEGS trong MyAnimals.

+0

Ah, tôi đã nghĩ rằng bất kể bạn định nghĩa lớp học ở đâu, hành động làm MyAnimals :: trên nó làm cho nó một lớp lồng nhau và cho nó truy cập vào phạm vi đó ... – jaydel

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