5

Ruby is fully object oriented language. In ruby, everything is an object & therefore, belongs to some class. for example 5 belongs to 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 

so, we have to call all methods by prefixing class/object name as in Object_name#method_name. example:

5.times{|i| puts i}

now, rails has these so called helpers like stylesheet_link_tag, javascript_include_tag, form_for etc which do follow this Object_name#method_name syntax, so i guess they are just normal functions.

so my question is

  1. What are these rails helpers?
  2. If they just functions & do not inherit from any class. Doesn't that contradict the claim made saying - in ruby, everything a object & there are no primitives. As the example, people cite 5.+(6) saying even operators are just plain methods?
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
CuriousMind
  • 33,537
  • 28
  • 98
  • 137

3 Answers3

8

For other things called without a receiver, look at the Kernel module, where stuff like puts is defined. Since the module is included in Object, its methods are available everywhere. How exactly would that contradict the -- IMHO overused -- claim that everything is an object?

Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
  • So these methods are defined in a module, instead of class? your answer has become my *aha* moment of the day. interesting! – CuriousMind May 18 '12 at 12:05
5

These rails assets tag helpers are a sub module of ActionView, ActionView::Helpers::AssetTagHelper which provides methods for generating HTML that links views to assets such as images, javascripts, stylesheets, and feed.

As modules have class as a superclass it mean that the AssetTagHelpers will also have it

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

NOTE: For sake of simplicity I will only focus on the JavascriptIncludeTag but they are all pretty similar.

Here you will find a class called ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag

Which you can be instantiate

JavascriptIncludeTag.new(config, asset_paths) 

The JavascriptIncludeTag class has a method called asset_tag which then calls a content_tag method and returns the correct tag.

path: /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

path: /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

So that is more less how they work.

NOTE: If you found my explanation a bit tricky just let me know and I'll edited to provide a better explanation

rogeliog
  • 3,632
  • 4
  • 27
  • 26
4

When you see method invocation without explicit receiver, then the receiver is self. Objects can get methods in many different ways. One, most obvious, is when you define methods yourself. Then you can also include modules.

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

Modules you include and classes you inherit from can acquire functionality in the same manner.

So, when you see method without receiver, think "what is self at this point? What is its class? What methods has it defined? What modules does it include?" You'll discover many interesting things about ruby and rails. :)

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367