2009-07-09 6 views
6

Tôi mới dùng Ruby và gần đây đã gặp phải vấn đề khi so sánh với các giá trị khi tạo ứng dụng Ruby on Rails. Trong bộ điều khiển, tôi có câu lệnh sau luôn trả về false:Kiểm tra cú pháp hoặc "Biên dịch" một ứng dụng Ruby on Rails

if (user.id != params[:id]) 

Vấn đề là user.id (là bản ghi hoạt động) là số nguyên và tham số [: id] là một chuỗi. Phải mất một lúc tôi mới hiểu được điều này và cuối cùng tôi đã thay đổi nó thành:

if (user.id != params[:id].to_i) 

Bây giờ tuyên bố hoạt động như mong đợi.

Để tránh lỗi này trong tương lai là có cách "biên dịch" hoặc yêu cầu Ruby cảnh báo bạn nếu bạn cố so sánh 2 loại khác nhau? Một số vấn đề khác mà tôi gặp phải mà tôi muốn "kiểm tra biên dịch" là:

  • Cảnh báo tôi nếu tôi tạo biến nhưng không sử dụng. Để giúp kiểm tra lỗi chính tả trong các tên biến.
  • Đảm bảo phương thức tồn tại trong Lớp để tôi có thể tránh lỗi chính tả tên phương pháp và cũng để giúp tái cấu trúc, ví dụ: nếu tôi đổi tên phương thức.

Tôi hiện đang sử dụng Ruby 1.8.6-27 RC2 với Rails 2.3.2 và RadRails IDE trên Windows.

+0

Vui lòng không có câu trả lời về việc kiểm tra mã của bạn. Tôi đã có một bài kiểm tra đơn vị cho đoạn mã trên và nó vẫn không thành công (cùng với kiểm tra thủ công của tôi) và tôi không thể hiểu tại sao. Những gì tôi đang tìm kiếm là một trình kiểm tra cú pháp cho Ruby tìm lỗi tương tự như trình biên dịch chuẩn sẽ tìm thấy. Thanx. –

+0

Trình biên dịch C sẽ không cung cấp cho bạn lỗi khi thực hiện 4 == 5.5. – Chuck

+0

Kiểm tra jetbrains ruby ​​ide, https://www.jetbrains.com/ruby/ –

Trả lời

0

Giải pháp tốt nhất mà tôi tìm thấy là IDE đã thực hiện kiểm tra cú pháp khi đang chạy, chẳng hạn như RubyMine. Tôi không chắc chắn nếu nó đã giải quyết vấn đề ban đầu của tôi nhưng nó đã giúp tôi tìm và sửa một số cú pháp khác và biên dịch lỗi. Cảm ơn mọi người vì sự gợi ý của mọi người.

5

Kiểm tra trước, sau đó mã. Nếu bạn viết các bài kiểm tra bao gồm tất cả các nhánh của ứng dụng của bạn, bạn sẽ có được sự đảm bảo rằng mã của bạn đều chạy và tạo ra các kết quả chính xác.

EDIT: Tôi nên chỉ ra rằng khả năng so sánh hai loại, không phụ thuộc vào tên phương pháp cho đến giây cuối cùng, vv là các tính năng cốt lõi của Ruby.

Bạn không gọi phương thức nhiều như bạn gửi tin nhắn đến một đối tượng. Đối tượng sau đó chịu trách nhiệm tìm ra cách xử lý phương thức. Trong Rails, nó được sử dụng để truy cập các cột DB trong ActiveRecord. Không có phương pháp nào cho các cột cho đến khi một thông báo có tên cột được gửi đến đối tượng.

Nhập tĩnh trong Ruby đi ngược lại hệ thống nhập vịt. Người ta thường có thể nhận được đa hình miễn phí mà không cần lo lắng về kế hoạch giao tiếp/kế thừa phức tạp.

Tôi khuyên bạn nên sử dụng các tính năng này và bù đắp cho sự không chắc chắn thông qua thử nghiệm

1

Ruby không được coi là an toàn. Nó cho phép bạn so sánh bất kỳ hai đối tượng nào, và đó là nơi có nhiều sức mạnh của nó. Rails sẽ không thể thực hiện được nếu không có thiết kế động.

Ngay cả một ngôn ngữ được biên dịch như Java hoặc C sẽ không ngăn bạn thực hiện == trên hai đối tượng. Như Ben đã nói, tốt nhất là nên kiểm tra trước. Kiểm tra các cấu trúc bạn đang làm việc. Một cách để có được thông tin về một đối tượng của Ruby là sử dụng:

puts object.class 
+0

p đối tượng, sẽ đổ ra một phiên bản chi tiết hơn của một đối tượng. trộn p và đặt thường là một người chiến thắng để nhận được thông tin gỡ lỗi. –

+0

Có. In là công cụ gỡ lỗi của tôi. Bạn cũng có thể sử dụng ./script/console để truy cập các đối tượng tương tác. – mcandre

1

Nói chung, cách tốt nhất (tôi biết) để tránh loại vấn đề cho các ngôn ngữ động/kịch bản là để di chuyển "logic" với các phương pháp/lệnh và viết các bài kiểm tra đơn vị cho chúng. Về cơ bản, bất cứ điều gì có thể thất bại nên được kiểm tra. Mã trên trang phải là logic ngu ngốc ... thay vì chỉ hiển thị các mục đáp ứng tiêu chí nhất định, nó sẽ hiển thị tất cả các mục và nhận danh sách các mục đó từ một phương thức chỉ trả về các mục sẽ được hiển thị.

2

Ruby không cho phép bạn xác định lại toán tử == cho đối tượng.Trong ruby ​​1.8 bạn không thể, Ruby 1.9 được cho là đã làm nhưng tôi đã không thể có được kịch bản của tôi làm việc cho các lớp cốt lõi. Nó hoạt động tốt cho các đối tượng được định nghĩa tùy chỉnh.

class Object 

    alias :equal_without_warning :== 

    def ==(object) 
    unless self.class == object.class 
     warn("Comparing `#{self.class}' with `#{object.class}'") 
    end 
    equal_without_warning(object) 
    end 

end 

Giả sử tôi không thực hiện một số lỗi mã ngu ngốc, câu trả lời là KHÔNG: bạn không thể kiểm tra xem bạn có đang so sánh các loại đối tượng khác nhau hay không.

Ngoài ra, tôi sẽ nói là bạn không. Trên thực tế Ruby không được thiết kế để làm việc theo cách này, đây là một cách tiếp cận java hơn là phong cách Ruby.

+0

Bạn sẽ phải thực hiện cùng một định nghĩa lại cho các lớp lõi vì chúng thường xác định lại == mà không cần tham chiếu đến Object # == – rampion

0

Hai điều tôi muốn đề xuất:

Một: Đã đọc trên IRB (hoặc tập lệnh/bàn điều khiển cho đường ray). Một thực tiễn phát triển chung trong ngôn ngữ động là thử các đoạn mã bên trong trình thông dịch "trực tiếp" (như IRB hoặc bảng điều khiển đường ray). Thực hành này quay trở lại các ngôn ngữ động sớm nhất như Smalltalk và Lisp. Ruby-debug cũng thực sự hữu ích cho các vấn đề xử lý sự cố và sẽ là một cách thực sự dễ dàng để tìm ra lỗi trong ví dụ của bạn.

Hai: Đọc trên "Nhập văn bản vịt". "Các loại" và các biến hoạt động hơi khác một chút trong Ruby so với nhiều người mong đợi chúng. Theo tôi hiểu nó, một biến như user.id không có một "loại". Giá trị được trỏ đến bởi user.id không có loại, nhưng chính biến đó thì không. Tôi tin rằng đó là một phần lý do tại sao không có công cụ nào có thể cho bạn biết lỗi của bạn là gì trước khi chạy chương trình. So sánh hai biến này không phải là lỗi vì các biến không có loại. user.id đã trỏ đến một số nguyên tại điểm đó trong chương trình của bạn, nhưng nó sẽ là hoàn toàn hợp pháp để gán user.id trỏ đến một chuỗi, tại thời điểm đó so sánh sẽ có ý nghĩa hơn rất nhiều. :-)

+0

Cũng không có lý do gì mà bạn không thể so sánh hai loại khác nhau với '=='. – Chuck