ruby真的是一个完全面向对象的语言吗?

时间:2012-05-18 11:44:32

标签: ruby-on-rails ruby ruby-on-rails-3

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_tagjavascript_include_tagform_for等,它们遵循此Object_name#method_name语法,所以我猜它们只是正常的函数。

所以我的问题是

  1. 这些铁路助手是什么?
  2. 如果他们只是功能&不要 继承任何类。这与提出的索赔是否相矛盾 说 - 在红宝石,everything a object & there are no primitives。 作为示例,人们引用5.+(6)说即使是运营商也只是 简单方法?

3 个答案:

答案 0 :(得分:8)

对于没有接收器的其他事情,请查看Kernel模块,其中定义了puts之类的内容。由于该模块包含在Object中,因此其方法随处可用。究竟是什么与IMHO过度使用相矛盾 - 声称一切都是对象?

答案 1 :(得分:5)

这些rails资产标记帮助程序是ActionView的子模块ActionView::Helpers::AssetTagHelper,它提供了生成HTML的方法,可以将视图链接到资源,如图像,javascripts,样式表和Feed。

由于modulesclass作为超类,这意味着AssetTagHelpers也会拥有它

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

这样他们的工作方式就更少了。

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

答案 2 :(得分:4)

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

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

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

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