2012-01-19 37 views
13

Tôi biết tính năng này do ActiveSupport cung cấp.Tôi làm cách nào để có được quyền truy cập băm kiểu JavaScript?

h = ActiveSupport::OrderedOptions.new 
h.boy = 'John' 
h.girl = 'Mary' 
h.boy # => 'John' 
h.girl # => 'Mary' 

Tuy nhiên tôi đã có một băm lớn và tôi muốn truy cập băm đó bằng ký hiệu chấm. Đây là những gì tôi đã thử:

large_hash = {boy: 'John', girl: 'Mary'} 
h = ActiveSupport::OrderedOptions.new(large_hash) 
h.boy # => nil 

Điều đó không hiệu quả. Làm thế nào tôi có thể thực hiện công việc này.

Tôi đang sử dụng ruby ​​1.9.2

Cập nhật:

Xin lỗi tôi có nên nói rằng tôi không thể sử dụng openstruct bởi vì nó không có each_pair phương pháp mà Struct có. Tôi không biết chìa khóa trước vì vậy tôi không thể sử dụng kiến ​​trúc mở.

+0

Hầu như một câu hỏi giống hệt nhau: http://stackoverflow.com/questions/2240535/ruby-hash-keys-as-methods-on-a-class –

+0

thể trùng lặp của [Ruby - phím Hash vào tên phương thức?] (http://stackoverflow.com/questions/6423484/ru by-hash-keys-to-method-name) –

Trả lời

9

OpenStruct nên làm việc độc đáo cho việc này.

Nếu bạn muốn xem làm thế nào nó hoạt động, hoặc có lẽ làm một phiên bản tùy chỉnh, bắt đầu với một cái gì đó như thế này:

h = { 'boy' => 'John', 'girl' => 'Mary' } 

class << h 
    def method_missing m 
    self[m.to_s] 
    end 
end 

puts h.nothing 
puts h.boy 
puts h.girl 
6

Bạn đang tìm kiếm OpenStruct

$ require 'ostruct' 
$ large_hash_obj = OpenStruct.new large_hash 
$ large_hash_obj.boy 
=> "John" 
+0

Xin lỗi tôi đã đề cập rằng tôi không thể sử dụng openstruct vì nó không có phương thức each_pair mà Struct có. Tôi không biết chìa khóa trước khi bàn tay vì vậy tôi không thể sử dụng kiến ​​trúc mở. –

4

I created my own gem for this, và tôi đã sử dụng nó trong tất cả các dự án của tôi. Dường như chỉ làm những gì bạn cần:

large_hash = { boy: 'John', girl: 'Mary' } 
r = Ribbon.wrap large_hash 

r.boy 
=> "John" 

r.girl 
=> "Mary" 

r.keys 
=> [:boy, :girl] 

r.each_pair { |key, value| puts "#{key} => #{value}" } 
boy => John 
girl => Mary 

Rất thích một số phản hồi.

3

Nếu nó chỉ là một kịch bản nhỏ nó an toàn để mở rộng Hash tự

class Hash 
    def method_missing sym,* 
    fetch(sym){fetch(sym.to_s){super}} 
    end 
end 

method_missing là một phương pháp kỳ diệu mà bất cứ khi nào được gọi là mã của bạn cố gắng gọi một phương thức không tồn tại. Ruby sẽ chặn cuộc gọi không thành công vào lúc chạy và cho phép bạn xử lý nó để chương trình của bạn có thể phục hồi một cách duyên dáng. Việc triển khai trên cố gắng truy cập vào hàm băm bằng cách sử dụng tên phương thức làm biểu tượng, sử dụng tên phương thức làm chuỗi và cuối cùng không thành công với phương thức tích hợp sẵn của lỗi thiếu của Ruby.

Đối với một ứng dụng phức tạp hơn, trong đó bổ sung thêm hành vi này cho tất cả băm có thể phá vỡ các mã khác hoặc third0party ngọc, sử dụng một mô-đun và mở rộng mỗi trường hợp

module H 
    def method_missing sym,* 
    fetch(sym){fetch(sym.to_s){super}} 
    end 
end 

the = { answer: 42 } 
the.extend(H) 
the.answer # => 42 

và để thuận tiện hơn, bạn thậm chí có thể tuyên truyền các mô-đun xuống để băm lồng nhau

module H 
    def method_missing sym,* 
    r = fetch(sym){fetch(sym.to_s){super}} 
    Hash === r ? r.extend(H) : r 
    end 
end 

the = { answer: { is: 42 } } 
the.extend(H) 
the.answer.is # => 42 
Các vấn đề liên quan