Dlaczego więc twórcy Ruby musieli zastosować tę koncepcję symbols
w języku?
Cóż, nie ściśle „musieli”, postanowili. Zauważ też, że ściśle mówiąc, Symbol
nie są częścią języka, są częścią podstawowej biblioteki. Oni nie mają składnię języka dosłownego poziomu, ale będą działać tak samo dobrze, jeśli trzeba było skonstruować je nazywając Symbol::new
.
Pytam z perspektywy nie-rubinowego programisty próbującego to zrozumieć. Nauczyłem się wielu innych języków i w żadnym z nich nie znalazłem potrzeby określania, czy mam do czynienia z tym, co nazywa Ruby symbols
.
Nie powiedziałeś, czym są te „wiele innych języków”, ale oto mały fragment języków, które mają Symbol
typ danych taki jak Ruby:
- ECMAScript , także JavaScript
- Scala
- Schemat , Common Lisp , Clojure (także, Clojure ma słowa kluczowe ), w zasadzie każdy język w rodzinie Lisp, jego następcy i kuzyni ma je
- Smalltalk , Newspeak i wiele innych języków z rodziny Smalltalk (co prawdopodobnie pochodzi od Ruby), w tym Objective-C (choć w ograniczonej formie)
- Erlang (zwane atomami ) , a także Eliksir i LFE
- Julia
- Prolog (zwany atomami ), który prawdopodobnie pochodzi od Erlanga
Istnieją również inne języki, które zapewniają funkcje Symbol
s w innej formie. Na przykład w Javie funkcje Ruby String
są podzielone na dwa (właściwie trzy) typy: String
i StringBuilder
/ StringBuffer
. Z drugiej strony, funkcje Ruby Symbol
typu są składane w języku Java String
Typ: Java String
s może być internowany , ciągami tekstowymi i String
y, które są wynikiem kompilacji oceniano wyrażenia stałe są automatycznie internowany, dynamicznie generowane String
s może być internowany przez wywołanie String.intern
metodą. Internowany String
w Javie jest dokładnie jak Symbol
w Ruby, ale nie jest zaimplementowany jako osobny typ, to po prostu inny stan niż JavaString
może być w. (Uwaga: we wcześniejszych wersjach Ruby, String#to_sym
kiedyś był wywoływany, String#intern
a ta metoda nadal istnieje jako starszy alias).
Główne pytanie może brzmieć: czy koncepcja języka symbols
Ruby istnieje jako zamiar wydajności w stosunku do siebie i innych języków,
Symbol
s są przede wszystkim typem danych o określonej semantyce . Ta semantyka umożliwia także implementację niektórych wydajnych operacji (np. Szybkie testowanie równości O (1)), ale to nie jest główny cel.
czy po prostu coś, co musi istnieć ze względu na sposób pisania języka?
Symbol
w języku Ruby wcale nie są potrzebne, bez nich Ruby działałaby dobrze. Są to wyłącznie funkcje biblioteczne. Jest dokładnie jedno miejsce w języku powiązanym z Symbol
s: def
wyrażenie definicji metody zwraca wartość Symbol
oznaczającą nazwę definiowanej metody. Jest to jednak dość niedawna zmiana, wcześniej wartość zwrotna była po prostu nieokreślona. MRI po prostu ocenił na nil
, Rubinius ocenił na Rubinius::CompiledMethod
obiekt i tak dalej. Możliwe byłoby również dokonanie oceny do UnboundMethod
… lub po prostu String
.
Czy program w Rubim byłby lżejszy i / lub szybszy niż jego, powiedzmy, odpowiednik Python lub Node? Jeśli tak, czy to z tego powodu symbols
?
Nie jestem pewien, o co tu pytasz. Wydajność zależy głównie od jakości wdrożenia, a nie od języka. Ponadto Node nie jest nawet językiem, to zdeklarowana platforma we / wy dla ECMAScript. Uruchomienie równoważnego skryptu na IronPython i MRI, IronPython prawdopodobnie będzie szybszy. Uruchomienie równoważnego skryptu na CPython i JRuby + Trufla, JRuby + Trufla prawdopodobnie będzie szybsze. Nie ma to nic wspólnego z Symbol
s, ale z jakością implementacji: JRuby + Truffle ma agresywnie optymalizujący kompilator, a także całą maszynę optymalizacyjną o wysokiej wydajności JVM, CPython to prosty interpreter.
Skoro jednym z zamierzeń Ruby jest łatwość czytania i pisania dla ludzi, czy jej twórcy nie mogą ułatwić procesu kodowania poprzez wdrożenie tych ulepszeń w samym tłumaczu (tak jak w innych językach)?
Nie. Nie Symbol
są optymalizacjami kompilatora. Są osobnym typem danych o specyficznej semantyce. Nie są jak flonum YARV , które są prywatną wewnętrzną optymalizacją dla Float
s. Sytuacja nie jest taka sama, jak w przypadku Integer
, Bignum
i Fixnum
, który powinien być niewidoczny prywatny wewnętrzny szczegół optymalizacja, ale niestety nie jest. (Jest to ostatecznie będzie ustalona w Ruby 2.4, który usuwa Fixnum
i Bignum
liści i tylko Integer
).
Robiąc to tak, jak robi to Java, ponieważ specjalny stan normalnych String
s oznacza, że zawsze musisz uważać na to, czy twoje String
są w tym szczególnym stanie, i w jakich okolicznościach są one automatycznie w tym szczególnym stanie, a kiedy nie. To znacznie większe obciążenie niż po prostu posiadanie osobnego typu danych.
Czy istniałaby zależna od języka definicja symboli i powód, aby mieć je w innych językach?
Symbol
to typ danych, który oznacza pojęcie nazwy lub etykiety . Symbol
s są obiektami wartości , niezmiennymi, zwykle natychmiastowymi (jeśli język je odróżnia), bezpaństwowcami i nie mają tożsamości. Dwie Symbol
równe są również zagwarantowane, że są identyczne, innymi słowy, dwie Symbol
równe są w rzeczywistości takie same Symbol
. Oznacza to, że równość wartości i równość odniesienia są tym samym, a zatem równość jest efektywna i O (1).
Powody, dla których mają je w języku, są naprawdę takie same, niezależnie od języka. Niektóre języki polegają na nich bardziej niż inne.
Na przykład w rodzinie Lisp nie ma pojęcia „zmiennej”. Zamiast tego jesteś Symbol
powiązany z wartościami.
W językach z możliwościami odblaskowych lub introspekcji, Symbol
a często są wykorzystywane do określenia nazwy odbitych podmiotów API refleksji, na przykład w Ruby Object#methods
, Object#singleton_methods
, Object#public_methods
, Object#protected_methods
, i Object#public_methods
zwracać Array
z Symbol
s (choć równie dobrze może zwracać Array
od Method
s). Object#public_send
przyjmuje Symbol
nazwę argumentu do wysłania jako argument (chociaż akceptuje również String
również, Symbol
jest bardziej semantycznie poprawny).
W ECMAScript Symbol
s to podstawowy element składowy zapewniający bezpieczeństwo ECMAScript w przyszłości. Odgrywają także dużą rolę w refleksji.