Ruby和Rails匹配的返回值..出乎意料



在RubyonRails Rails教程中介绍Ruby类和继承时,Michael Hartl问为什么在Rails控制台中运行static_pages_controller.rb时,在StaticPagesController对象上调用操作时会返回nil

class StaticPagesController < ApplicationController
def home
end
...
end

在轨道控制台中:

>> controller = StaticPagesController.new
=> #<StaticPagesController:0x22855d0> (*)
>> controller.home
=> nil

(*)(我的rails c返回与对象相关的属性,但它们在第二版中没有显示,但我使用的是rails 4.0.2,我相信他使用的是rails 3,这可能是我问题的答案,但我们拭目以待)

具体而言,他提出以下问题:

但是等待--操作不会返回值,至少不会返回重要的值。home作用的要点。。。是呈现网页,而不是返回值。。。怎么回事?

他的答案只是Rails不是Ruby:

Rails是用Ruby编写的,但Rails不是Ruby。一些Rails类的使用方式与普通Ruby对象类似,但有些类只是Rails的魔法工厂的一部分。[增加强调]

我的问题是,为什么这算是答案?当我在IRB中运行相同的命令时(在创建了自己的StaticPagesController类之后——尽管它不是从Rails的ActionController继承的),我也会得到一个nil返回值:

My-Computer:app_root_directory David$ rails c
2.0.0p353 :001 > controller = StaticPagesController.new
2.0.0p353 :009 > controller.home
=> nil 
2.0.0p353 :010 > exit
My-Computer:app_root_directory David$ irb
cannot load such file -- hirb
>> class Controller
>> def home
>> end
>> end
=> nil
>> controller = Controller.new
=> #<Controller:0x007ff365299c70>
>> controller.home
=> nil

基本上,我问这个问题是小题大做吗?不理解他为什么要强调为什么一个操作(实际上只是控制器类的一个方法)在Rails控制台中调用时返回nil,这可以吗?

我认为你误解了这个问题。如果你像看待普通Ruby类一样看待控制器,那么home方法。。。毫无意义。它没什么意思(返回零有点无聊)。作为一个Ruby程序员,你不会把它放在那里,因为Ruby程序员声明方法是为了使用它们(所以它们应该返回一个值,或者只是做一些可观察的事情)

另一方面,在Rails中,操作(甚至是空的)是MVC模式的重要组成部分。您声明这些方法,但从不调用它们(至少不是显式调用),因为在Rails中,它不仅仅是一个方法,它是告诉Rails该做什么的一种方式

这就是为什么他强调Rails不是Ruby,尤其是当你将它与Capybara和Cocumber这样的宝石一起使用时。它们是领域特定语言(DSL)。是的,他们使用Ruby,但他们不是Ruby

在ruby中,所有都返回一个对象。因此,"操作不返回值"这句话在技术上是不正确的。如果没有其他内容的上下文,我猜他的意思是在Rails请求生命周期中调用一个操作不会返回您关心的值。在Rails堆栈的某个位置,对操作的调用返回一个对象,但它与您的开发无关。

至于控制台输出,您只得到nil,因为您的操作是空的。如果您将操作定义更改为:

def home
1
end

然后你会收到1作为你的返回对象,无论是在Rails上下文中还是在它之外。我认为另一个关键点是把nil看作一个值,只是一个代表没有值的值。

最新更新