2012-05-18 7 views
5

Ruby to w pełni zorientowany obiektowo język. W rubinach wszystko jest przedmiotem &, dlatego należy do jakiejś klasy. na przykład 5 należący do Object classCzy ruby ​​naprawdę są językiem w pełni zorientowanym na obiekt?

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 

tak, musimy zadzwonić wszystkich metod poprzedzając nazwę klasy/przedmiot jak w Object_name#method_name. Przykład:

5.times{|i| puts i} 

teraz, szyny ma tak zwanych pomocników jak stylesheet_link_tag, javascript_include_tag, form_for etc, które przestrzegają tej składni Object_name#method_name, więc sądzę, że są one po prostu normalne funkcje.

więc moje pytanie jest

  1. Jakie są te szyny pomocników?
  2. Jeśli po prostu działają &, nie dziedziczą z żadnej klasy. Czy nie jest to sprzeczne z oświadczeniem złożonym w rubryce , everything a object & there are no primitives. Jako przykład, ludzie cytują 5.+(6) twierdząc, że nawet operatorzy są po prostu prostych metod?
+1

Kiedy widzisz wywołania metody bez wyraźnej odbiornika, wówczas odbiornik jest 'self'. Jak dokładnie stwierdziłeś, że "wszystko jest przedmiotem", nie jest prawdą? –

+0

Ohk, nie wiedziałem o "self". Sądzę, że się myliłem, dzięki! – CuriousMind

+1

Uaktualnię to do odpowiedzi :) –

Odpowiedz

8

Dla innych rzeczy zwanych bez odbiornika, spojrzeć na module Kernel, gdzie takie rzeczy puts jest zdefiniowana. Ponieważ moduł jest zawarty w Object, jego metody są dostępne wszędzie. Jak dokładnie byłoby to sprzeczne z - nadużywanym przez IMHO - twierdzić, że wszystko jest przedmiotem?

+0

Więc te metody są zdefiniowane w module, a nie w klasie? Twoja odpowiedź stała się moją * aha * chwilą dnia. ciekawy! – CuriousMind

4

Po wyświetleniu wywołania metody bez jawnego odbiornika, odbiorcą jest self. Obiekty mogą uzyskać metody na wiele różnych sposobów. Jednym z najbardziej oczywistych jest to, kiedy sam definiujesz metody. Następnie możesz także dołączyć moduły.

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

Dołączane moduły i klasy, od których dziedziczysz, mogą uzyskać funkcjonalność w ten sam sposób.

Tak więc, gdy widzisz metodę bez odbiornika, pomyśl "co to jest self w tym miejscu? Jaka jest jego klasa? Jakie metody to zdefiniowała? Jakie moduły zawiera?" Odkryjesz wiele interesujących rzeczy o rubinach i szynach. :)

5

Te pomocnicze znaczniki railsów są pod modułem ActionView, ActionView::Helpers::AssetTagHelper, który zapewnia metody generowania kodu HTML, który łączy widoki z zasobami takimi jak obrazy, javascripts, arkusze stylów i kanały.

Jak modules mieć class jako nadrzędnej to oznaczać, że AssetTagHelpers będzie również mieć to

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 

UWAGA: Dla uproszczenia skupię się tylko na JavascriptIncludeTag ale wszystkie są bardzo podobne.

Tutaj znajdziesz klasę o nazwie ActionView::Helpers::AssetTagHelper::JavascriptIncludeTag

które można mieć instancję

JavascriptIncludeTag.new(config, asset_paths) 

Klasa JavascriptIncludeTag ma metodę zwaną asset_tag które następnie wywołuje metodę content_tag i zwraca poprawny tag.

ścieżka: /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 

ścieżka: /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 

tak, że jest mniej mniej, jak działają.

UWAGA: Jeśli znalazłeś moje wyjaśnienie nieco kłopotliwe tylko daj mi znać, a ja edytowany w celu zapewnienia lepszego wyjaśnienia

Powiązane problemy