我是Ruby的新手,最近遇到了一个与创建Ruby on Rails应用程序时的值相比较的问题。在控制器中,我有以下语句总是返回false:
if (user.id != params[:id])
问题是user.id(活动记录)是一个整数,params [:id]是一个字符串。我花了一段时间来弄清楚这一点,最后我把它变成了:
if (user.id != params[:id].to_i)
现在声明按预期工作。
为了避免将来出现这种错误,有没有办法“编译”或让Ruby在你尝试比较两种不同的类型时发出警告?我遇到的其他一些我想要“编译检查”的问题是:
我目前正在Windows上使用带有Rails 2.3.2和RadRails IDE的Ruby 1.8.6-27 RC2。
答案 0 :(得分:5)
首先测试,然后测试代码。如果编写涵盖应用程序所有分支的测试,则可以确保代码运行并产生正确的结果。
编辑:我应该指出,比较两种类型的能力,不依赖于方法名称直到最后一秒,等等是Ruby的核心功能。您不会像向对象发送消息那样调用方法。然后,该对象负责确定如何处理该方法。在Rails中,这用于访问ActiveRecord中的DB列。在将具有列名称的消息发送到对象之前,没有列的方法。
Ruby中的静态类型违反了duck typing系统。人们经常可以免费获得多态性,而不必担心复杂的继承/接口方案。
我建议采用这些功能并通过测试来弥补不确定性
答案 1 :(得分:2)
Ruby不允许您重新定义Object的==运算符。在ruby 1.8中你不能,Ruby 1.9应该这样做,但我无法让我的脚本为核心类工作。它适用于自定义对象。
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
假设我没有做一些愚蠢的编码错误,答案是否定的:您无法检查是否在比较不同类型的对象。
另外,我会说你没有。实际上Ruby不是以这种方式工作的,这更像是一种java方法,而不是Ruby风格。
答案 2 :(得分:1)
Ruby不应该是安全的。它可以让你比较任何两个对象,而这正是它的大部分功能来自的地方。没有这种动态设计,就不可能使用Rails。
即使是Java或C等编译语言也不会阻止你对两个对象进行==操作。正如Ben所说,最好先测试一下。检查您正在使用的结构。获取有关Ruby对象的信息的一种方法是使用:
puts object.class
答案 3 :(得分:1)
通常,为了避免动态/脚本语言的这种类型的问题,最好的方法(我知道)是将“逻辑”移动到方法/命令并为它们编写单元测试。基本上,任何可能失败的东西都应该进行测试。页面上的代码应该是哑逻辑...而不是仅显示满足特定条件的项目,它应显示所有项目,并从仅返回应显示的项目的方法中获取项目列表。 / p>
答案 4 :(得分:0)
我建议的两件事:
一:读取IRB(或脚本/控制台的rails)。动态语言中的一个常见开发实践是在“实时”解释器(如IRB或rails控制台)内部尝试代码片段。这种做法可以追溯到最早的动态语言,如Smalltalk和Lisp。 Ruby-debug对于解决问题非常有用,并且可以很容易地找出示例中的错误。
二:阅读“Duck Typing”。 Ruby中的“类型”和变量的工作方式与许多人期望的不同。据我了解,像user.id这样的变量没有“类型”。 user.id指向的值确实有一个类型,但变量本身没有。我相信这就是为什么没有工具可以告诉你在运行程序之前你的错误是什么的一部分。比较这两个变量不是错误,因为变量没有类型。 user.id指向程序中该点的整数,但将user.id指向一个字符串是完全合法的,此时比较会更有意义。 : - )
答案 5 :(得分:0)
我找到的最佳解决方案是一个可以进行动态语法检查的IDE,例如RubyMine。我不确定它是否能解决我原来的问题,但它帮助我找到并修复了其他一些语法和编译错误。谢谢大家的建议。