03
czerwca
2009
Zastanawiałem się ostatnio nad zdaniem w kontekście języka Ruby:
Wszystko jest obiektem.ruby-lang.org/pl/
Ciekawe, czy faktycznie do wszystkiego można w nim zastosować konstrukcje świadczące o wykorzystaniu obiektowości, a jak w przykładzie widać:
MyClass = Class.new do
attr_accessor :instance_var
end
klasy można tworzyć także poprzez bloki kodu przekazywane do metody Class::new. Bardzo to sprytne i takie obiektowe(!). To znaczy, można skończyć z pseudoobiektowym kodem w stylu:
class MyClass
attr_accessor :instance_var
end
i zacząć programować w pełni obiektowo!
Czyli, a jak ustawić klasę nadrzędną? Argumentem!
MySuperClass = Class.new do
def foo
"bar"
end
end
MyClass = Class.new(MySuperClass) do
def foo
"bar2"
end
end
No to pomyślmy nad zastosowaniem. Po pierwsze: możliwość tworzenia klas dynamicznie bez zbędnego evalowania tekstu:
module WeirdClasses
error_classes = %w{FooBarError ClassNotExistsInScope BarIsNotFoo BazAlreadyDefined}
error_classes.each do |class_name|
const_set class_name, Class.new(StandardError)
end
end
WeirdClasses::FooBarError.superclass
=> StandardError
lub jak znalazłem w sieci:
def Exception(*names)
cl = Module === self ? self : Object
names.each {|n| cl.const_set(n, Class.new(Exception))}
end
#użycie:
Exception "Foo"
module Bar
Exception "Unknown", "Stuff"
end
begin
raise Foo, "where?"
rescue Exception => e
p e
end
begin
raise Bar::Stuff, "where?"
rescue Exception => e
p e
end
Drugie zastosowanie jest poniekąd rozwinięciem pierwszego. Zauważmy, że blok kodu klasy ( do end ) jest w rzeczywistości zwykłym kawałkiem kodu (czyli obiektem klasy Proc).
Możemy współdzielić tę samą architekturę klasy bez dziedziczenia (pomijam celowość). Np.
module FunnyEqualClasses
class_content = Proc.new do
def my_method
"this method belongs to #{self.class.to_s}"
end
end
similar_classes = %w{Foo Bar Baz Etecera}
similar_classes.each do |c|
const_set c, Class.new(&class_content)
end
end
FunnyEqualClasses::Foo.new.my_method
=> "this method belongs to FunnyEqualClasses::Foo"
W obu powyższych przykładach użyłem magicznego const_set wewnątrz module aby utworzyć stałe dla poszczególnych klas. Wynik jest przynajmniej elegancki, ale co ciekawe, Ruby wcale nie limituje, aby klasy były stałymi! Mogą być one równie dobrze też i zmienną:
normal_var = Class.new {
def some_method
101
end
}
obj = normal_var.new
=> #<#:0x5c37a8>
obj.some_method
=> 101
normal_var = Class.new {
def some_method
"111"
end
}
obj.some_method
=> 101
obj2 = normal_var.new
=> <#:0x5e1280>
obj2.some_method
=> "111"
Co zauważamy? Że raz utworzony obiekt danej klasy pamięta z czego powstał i nie traci tej informacji, mimo że pod zmienną z której powstał znajduje się już inna klasa. Dziwne zachowanie języka, ale skutecznie zapobiega osieroceniu obiektów.
Oczywiście w przypadku stałych i tutaj możemy nadpisywać raz utworzone - tyle tylko, że po zmianie wartości stałej dostaniemy warning.
To w zasadzie na tyle. Miło byłoby usłyszeć, co wy myślicie o takim zastosowaniem obiektowości języka Ruby albo poznać wasze sposoby zastosowania tak obiektowego podejścia.
Polecam http://scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR.mp4 Wszystko staje sie prostsze.
A artykuł jak dla mnie bardzo pokrętnie i zawile napisany, nie jestem pewien czy początkujący by to ogarnął.
Artykuł jest pewnym tokiem myśli związanych z bardziej obiektowym pisaniem klas.
Tym co podejrzewam o rozpraszanie jest prawdopodobnie forma – mój szablon ma takie dziwne style dla akapitów, gdy poprzednikiem jest inny kod niż <p>.
A co do prezentacji Dave’a Thomasa – to widziałem. Tyle, że on pokazuje jeszcze magiczniejsze właściwości języka. ;)
No i tak właściwie, to nie zamierzałem pisać dla newbie, a dla osób które już ogarnęły jakieś „Pickaxe” albo inne „RubyWay”.
№ 3
03 czerwca 2009, 10:00:54
lionix
Czyżby autorowi chodziło o koncepcje metaklasy?
Nie znam się na ruby ale myślę że właśnie taka idea przyświecała autorowi, chociaż moim zdaniem metaklasy mają większe możliwości.
dziwne zachowanie języka ? toż to wdrożono nie później niż w 1976 (a prawdopodobnie znacznie wcześniej). Koncepcja z początku pewnie wydawała się ludziom dziwna ale w czasach Rubego (od 1993, dobrze pamiętam ?) jest powszechnie przyjęta i stosowana. Oczywiście reguła domknięcia jest uniwersalna i nie chodzi tu tylko o klasy i ich instancje.
Nie mogę tego zrozumieć, ale może dlatego że nie chce mi się narazie skupiać nad takimi problemami.