Vị trí tốt nhất để thêm phương thức vào lớp số nguyên trong Rails ở đâu? Tôi muốn thêm một phương thức to_meters
và to_miles
.Đâu là nơi tốt nhất để thêm các phương thức vào lớp Integer trong Rails?
Trả lời
Nếu bạn đã đặt trái tim của mình trên mucking với lớp Số (hoặc số nguyên, v.v.) để chuyển đổi đơn vị, thì ít nhất hãy thực hiện nó một cách logic và với một số giá trị thực.
Đầu tiên, tạo một lớp Đơn vị lưu trữ loại đơn vị (mét, chân, hình khối, v.v ...) và giá trị khi tạo. Sau đó, thêm một loạt các phương thức vào Số tương ứng với đơn vị giá trị hợp lệ có thể có: các phương thức này sẽ trả về một đối tượng Đơn vị với kiểu của nó được ghi là tên phương thức. Lớp Đơn vị sẽ hỗ trợ một loạt các phương thức to_ * sẽ chuyển đổi thành một loại đơn vị khác với giá trị đơn vị tương ứng. Bằng cách đó, bạn có thể làm lệnh sau:
>> x = 47.feet.to_meters
=> 14.3256
>> x.inspect
=> #<Unit 0xb795efb8 @value=14.3256, @type=:meter>
Cách tốt nhất để xử lý nó có lẽ sẽ là một ma trận của các loại chuyển đổi và biểu thức trong lớp đơn vị, sau đó sử dụng method_missing để kiểm tra xem một loại nhất định có thể được chuyển đổi sang loại khác. Trong lớp số, sử dụng method_missing để hỏi Unit nếu nó hỗ trợ phương thức đã cho như là một loại đơn vị, và nếu như vậy, trả về một đối tượng đơn vị của kiểu được yêu cầu bằng cách sử dụng số làm giá trị của nó. Sau đó bạn có thể hỗ trợ thêm các đơn vị và chuyển đổi khi chạy bằng cách thêm một phương thức register_type và register_conversion vào Đơn vị mở rộng ma trận chuyển đổi và Numeric sẽ "tự động" nhận khả năng.
Đối với vị trí đặt, hãy tạo tệp lib/units.rb, cũng sẽ chứa tệp monkey_patch thành Số, sau đó khởi chạy nó trong config/environment.rb bu yêu cầu tệp lib/units.rb.
thường (và logic), số nguyên không thể được chuyển đổi sang dặm hoặc để mét. Có vẻ như bạn có thể muốn tạo một lớp mới như "Feet" hoặc "inches" được khởi tạo với một số nguyên, sau đó chứa các phương thức như size_in_miles hoặc size_in_meters. Để thuận tiện các phương pháp đó có thể trở lại thập phân hoặc nổi các loại, nhưng bạn cũng có thể muốn viết một lớp dặm hoặc một lớp mét.
Là một phương pháp thay thế, bạn có thể muốn tạo ra một phương pháp tĩnh trong lớp mới của bạn mà có thể có một chữ ký như thế này:
Float feetToMiles(integer I)
rằng bạn sẽ gọi
miles = Feet.feetToMiles(5280);
và nhận được miles = 1.0
Tạo mô-đun/thư viện của riêng bạn ch bạn đưa vào phạm vi khi bạn cần nó để thực hiện tác vụ này.
Chẳng hạn như "requre 'unitCoversions"
Và Rất có thể, ai đó đã làm điều này nếu bạn nhìn cứng đủ :)
Tuy nhiên DONT thử sửa đổi các lớp lõi bản xứ, mà sẽ chỉ kết thúc trong Misery.
(Ngoài ra, lớp bạn muốn mở rộng là 'số', mà sẽ áp dụng cho cả Số nguyên và Floats :))
Không hoàn toàn rõ ràng lý do tại sao tôi không nên làm điều này ... Rails làm điều này cho lớp chuỗi thành công lớn.
Bởi vì nó có thể được thực hiện không có nghĩa là nó nên được thực hiện. 'Khỉ Patching' vì nó được biết đến có thể có tất cả các loại tác dụng phụ lạ, và họ có thể là một thất bại sử thi khi làm sai.
Làm khi không có lựa chọn thay thế tốt.
Vì nếu bạn thực sự muốn làm điều gì đó, bạn có thể xây dựng toàn bộ khuôn khổ TẤT CẢ nó đã làm khỉ vá các lớp lõi.
Ví dụ: lật dữ liệu trên đầu của nó.
5.getArtist();
10.getEvent();
100.getTrack();
v.v. không có giới hạn về số lượng cách xấu để thực hiện điều đó.
"Bob".createUser();
đau khổ trong cốc.
Nếu bạn muốn làm điều gì đó thực tế, có một lớp Chuyển đổi hoặc chức năng,
convert(3 , { :from=>:miles, :to=>:meters });
ít nhất bạn không làm ô nhiễm các chức năng namespace và lõi toàn cầu như vậy và nó có ý nghĩa mạch lạc hơn.
Không hoàn toàn rõ ràng lý do tại sao tôi không nên làm điều này ... Rails thực hiện điều này với lớp chuỗi thành công lớn. – Ben
Nếu bạn đang đi để làm điều này, mà bạn không nên, sau đó bạn sẽ đặt mã của bạn vào:
config/initializers/add_methods_that_are_naughty_to_numeric.rb
Rails sẽ tự động chạy những cho bạn.
Tại sao không chỉ:
class Feet
def self.in_miles(feet)
feet/5280
end
end
sử dụng:
Feet.in_miles 2313
Hoặc có thể nhìn vào nó theo cách khác:
class Miles
def self.from_feet(feet)
feet/5280
end
end
Miles.from_feet 2313
Tôi đồng ý khỉ vá nên được sử dụng một cách cẩn thận, nhưng đôi khi nó chỉ có ý nghĩa. Tôi thực sự thích những người trợ giúp cho phép bạn nhập 5.days.ago là một phần của thư viện active_support
Vì vậy, một số câu trả lời khác có thể tốt hơn trong trường hợp này, nhưng nếu bạn đang mở rộng lớp ruby, chúng tôi giữ tất cả các tiện ích mở rộng trong lib/extensions/class_name.rb
cách này khi làm việc trên một dự án nhanh chóng và dễ dàng để tìm và xem mọi thứ có thể không bình thường với các lớp tiêu chuẩn.
Nhận ra câu hỏi là cũ, nhưng tôi nghĩ cách rõ ràng nhất là tạo lớp Khoảng cách với hai thuộc tính @length
và @unit
.
Bạn chỉ cần một băm chuyển đổi, có lẽ như là một biến lớp học của Khỏang cách:
class Distance
@@conversion_rates = {
meters: {
feet: 3.28084,
meters: 1.0
}
}
def to(new_unit)
new_length = @length * @@conversion_rates[@unit][new_unit]
Distance.new(new_length, new_unit)
end
end
Và nó sẽ trông kinda thích:
Distance.new(3, :meters).to(:feet)
mà tôi thật sự nghĩ trông tốt hơn so với
3.meters.to_feet
- 1. Rails 3: Nơi tốt nhất để đặt các lớp trình xác nhận tùy chỉnh ở đâu?
- 2. Đâu là nơi tốt nhất để lưu trữ ảnh toàn cầu trong ứng dụng Rails?
- 3. Cách tốt nhất để thêm chú thích vào các phương thức kế thừa
- 4. Đâu là nơi tốt nhất để lưu các tệp tạm thời trong Windows
- 5. Đâu là nơi tốt nhất để lưu trữ hình ảnh cầu vồng (auth token) trong Android
- 6. Nơi tốt nhất cho các lớp python trong dự án Django là gì?
- 7. Thêm phương thức vào một lớp miền
- 8. Cách tốt nhất để thêm các mục vào cửa sổ phương thức của một ứng dụng khác là gì?
- 9. Nơi nào là nơi tốt nhất để xác định một hằng số trong ứng dụng Ruby on Rails?
- 10. Làm thế nào để vượt qua các phương pháp tốt nhất vào các phương thức của cùng một lớp
- 11. Cách tốt nhất để chia sẻ các phương thức trong các lớp trong Mục tiêu C là gì?
- 12. Cách thêm phương thức vào lớp hiện có trong PHP?
- 13. Đâu là nơi tốt nhất để chỉ định kho lưu trữ maven, pom.xml hoặc settings.xml?
- 14. Nơi tốt nhất để bắt đầu học Qt là gì?
- 15. đâu là nơi tốt nhất để đặt #ifdef __cplusplus extern "C" {#endif
- 16. Nơi tốt nhất để lưu trữ các hằng số trong ứng dụng iOS ở đâu?
- 17. Cách tốt nhất để thêm nhận xét Disqus vào ứng dụng Rails là gì?
- 18. Tại sao toBinaryString không phải là một phương thức thể hiện trong lớp Integer?
- 19. Thêm thuộc tính vào các phương thức mẫu trong Python
- 20. thêm phương thức vào lớp tích hợp trong ứng dụng đường ray
- 21. Thêm cùng một phương thức vào nhiều lớp
- 22. Đâu là nơi tốt để bắt đầu lập trình GUI cho các cửa sổ?
- 23. Thêm phương thức Thêm vào mảng ActiveRecord
- 24. Phương thức lớp vs hằng số trong Ruby/Rails
- 25. Phương thức xác thực tốt nhất để cấp quyền truy cập API cho ứng dụng Rails
- 26. Tôi có thể thêm các phương thức mới vào lớp String trong Java không?
- 27. thêm phương thức vào một lớp động với trang trí
- 28. Thêm phương thức mở rộng vào lớp chuỗi - C#
- 29. động thêm các phương pháp lớp học để một lớp
- 30. Trình biên dịch lưu trữ các phương thức cho các lớp C++ ở đâu?
Điều duy nhất tôi đề nghị làm khác là làm khởi tạo bằng cách sử dụng thư mục initializers thay vì trong environment.rb. Bài đăng tuyệt vời. – jonnii