5

Ruby 是完全面向对象的语言。在 ruby​​ 中,一切都是对象,因此属于某个类。例如5属于Object class

1.9.3p194 :001 > 5.class
 => Fixnum 
1.9.3p194 :002 > 5.class.superclass
 => Integer 
1.9.3p194 :003 > 5.class.superclass.superclass
 => Numeric 
1.9.3p194 :005 > 5.class.superclass.superclass.superclass
 => Object 
1.9.3p194 :006 > 5.class.superclass.superclass.superclass.superclass
 => BasicObject 
1.9.3p194 :007 > 5.class.superclass.superclass.superclass.superclass.superclass
 => nil 

因此,我们必须通过在类/对象名称前面加上前缀来调用所有方法,如Object_name#method_name. 例子:

5.times{|i| puts i}

现在,rails 有这些所谓的助手,比如stylesheet_link_tag,等javascript_include_tagform_for它们确实遵循这种Object_name#method_name语法,所以我猜它们只是普通函数。

所以我的问题是

  1. 这些导轨助手是什么?
  2. 如果它们只是功能并且不从任何类继承。这不与声称的说法相矛盾 - 在红宝石中,everything a object & there are no primitives. 例如,人们引用5.+(6)说即使运算符也只是简单的方法?
4

3 回答 3

8

对于其他没有接收器调用的东西,请查看Kernel模块,其中puts定义了类似的东西。由于该模块包含在 中Object,因此其方法随处可用。这与 - 恕我直言过度使用 - 声称一切都是对象的说法究竟有何矛盾?

于 2012-05-18T11:50:32.260 回答
5

这些 rails assets 标签助手是 ActionView 的一个子模块,ActionView::Helpers::AssetTagHelper它提供了生成 HTML 的方法,这些 HTML 将视图链接到图片、javascript、样式表和提要等资产。

作为一个超类,这意味着 AssetTagHelpers 也将拥有modulesclass

irb(main):016:0> ActionView::Helpers::AssetTagHelper
=> ActionView::Helpers::AssetTagHelper
irb(main):017:0> ActionView::Helpers::AssetTagHelper.class
=> Module
irb(main):018:0> ActionView::Helpers::AssetTagHelper.class.superclass
=> Object
irb(main):019:0> ActionView::Helpers::AssetTagHelper.class.superclass.superclass
=> BasicObject
irb(main):020:0> ActionView::Helpers::AssetTagHelper.class.superclass.superclass.superclass
=> nil

注意:为简单起见,我将只关注 JavascriptIncludeTag,但它们都非常相似。

在这里,您将找到一个名为ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag

你可以实例化哪个

JavascriptIncludeTag.new(config, asset_paths) 

JavascriptIncludeTag 类有一个方法被调用asset_tag,然后调用一个content_tag方法并返回正确的标签。

路径:/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb

require 'action_view/helpers/asset_tag_helpers/asset_include_tag'

# NOTE: on the 'action_view/helpers/asset_tag_helpers/asset_include_tag' it requires '/actionpack/lib/action_view/helpers/tag_helper.rb' so now all this files are connected :)
.
.
.
def asset_tag(source, options)
  content_tag("script", "", { "src" => path_to_asset(source) }.merge(options))
end

路径:/actionpack/lib/action_view/helpers/tag_helper.rb

def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
  if block_given?
    options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
    content_tag_string(name, capture(&block), options, escape)
  else
    content_tag_string(name, content_or_options_with_block, options, escape)
  end
end

因此,它们的工作方式就更少了。

注意:如果您发现我的解释有点棘手,请告诉我,我会进行编辑以提供更好的解释

于 2012-05-18T12:39:00.523 回答
4

当您看到没有显式接收器的方法调用时,接收器是self. 对象可以通过许多不同的方式获取方法。一,最明显的是,当您自己定义方法时。然后您还可以包含模块。

class Person
  # this adds a bunch of methods to Person, making it a Mongoid model
  include Mongoid::Document
end

您包含的模块和您继承的类可以以相同的方式获取功能。

所以,当你看到没有接收器的方法时,想一想“self此时是什么?它的类是什么?它定义了哪些方法?它包含哪些模块?” 你会发现很多关于 ruby​​ 和 rails 的有趣的东西。:)

于 2012-05-18T12:07:46.950 回答