Kontynuując mem "Ukryte cechy ...", podzielmy się mniej znanymi, ale użytecznymi cechami języka programowania Ruby.
Spróbuj ograniczyć tę dyskusję do rdzenia Rubiego, bez żadnych rzeczy związanych z Ruby on Rails.
Zobacz też:
- Ukryte funkcje języka C #
- Ukryte funkcje Java
- Ukryte funkcje JavaScript
- Ukryte funkcje Ruby on Rails
- Ukryte funkcje Pythona
(Proszę, tylko jedna ukryta funkcja na odpowiedź.)
Dziękuję Ci
ruby
hidden-features
składu
źródło
źródło
Odpowiedzi:
Od Ruby 1.9 Proc # === jest aliasem do wywołania Proc #, co oznacza, że obiekty Proc mogą być używane w instrukcjach case, takich jak:
źródło
Peter Cooper ma dobrą listę sztuczek Ruby. Być może moim ulubionym z jego dzieł jest umożliwienie wyliczenia zarówno pojedynczych przedmiotów, jak i kolekcji. (To znaczy traktuj obiekt niebędący kolekcją jako kolekcję zawierającą tylko ten obiekt). Wygląda to tak:
źródło
items
jest łańcuchem, nie musisz go otaczać [*…]. String.each nie wykonuje iteracji po znakach, jak niektórzy mogą się spodziewać. Po prostu wraca do bloku.Nie wiem, jak to jest ukryte, ale uznałem to za przydatne, gdy potrzebowałem zrobić hasz z jednowymiarowej tablicy:
źródło
Hash[ [["apple","red"], ["banana","yellow"] ]
daje ten sam wynik.Jedną ze sztuczek, które lubię, jest użycie
*
ekspandera splat ( ) na obiektach innych niż Arrays. Oto przykład dopasowania wyrażenia regularnego:Inne przykłady obejmują:
źródło
text, number = *"text 555".match(/regexp/)[1..-1]
.text, number = "Something 981".scan(/([A-z]*) ([0-9]*)/).flatten.map{|m| Integer(m) rescue m}
Wow, nikt nie wspomniał o operatorze flip flop:
źródło
i == 3
i zmienia się na fałsz poi != 3
ii == 15
. Podobny do flip-flop: en.wikipedia.org/wiki/Flip-flop_%28electronics%29Jedną z fajnych rzeczy w Ruby jest to, że możesz wywoływać metody i uruchamiać kod w miejscach, na które inne języki by się nie podobały, na przykład w definicjach metod lub klas.
Na przykład, aby utworzyć klasę, która ma nieznaną nadklasę do czasu uruchomienia, tj. Jest losowa, możesz wykonać następujące czynności:
Używa
Array#sample
metody 1.9 (tylko w 1.8.7, zobaczArray#choice
), a przykład jest dość wymyślony, ale możesz zobaczyć tutaj moc.Innym fajnym przykładem jest możliwość umieszczenia domyślnych wartości parametrów, które nie są stałe (jak często wymagają inne języki):
Oczywiście problem z pierwszym przykładem polega na tym, że jest on oceniany w czasie definicji, a nie w czasie połączenia. Tak więc, po wybraniu superklasy, pozostaje nią do końca programu.
Jednak w drugim przykładzie, za każdym razem, gdy wywołasz
do_something_at
,at
zmienną będzie czas wywołania metody (cóż, bardzo, bardzo blisko)źródło
require 'activesupport'
Kolejna mała funkcja - zamień a
Fixnum
na dowolną bazę do 36:Jak skomentował Huw Walters, konwersja w drugą stronę jest równie prosta:
źródło
String#to_s(base)
może służyć do konwersji z powrotem na liczbę całkowitą;"1001001100101100000001011010010".to_i(2)
,"499602d2".to_i(16)
Etc wszystkim zwraca oryginałFixnum
.Hashe z wartościami domyślnymi! Tablica w tym przypadku.
Bardzo przydatne w metaprogramowaniu.
źródło
Pobierz źródło Ruby 1.9 i wydaj
make golf
, a następnie możesz zrobić takie rzeczy:Przeczytaj
golf_prelude.c
więcej schludnych rzeczy, które się ukrywają.źródło
Kolejnym fajnym dodatkiem do funkcjonalności 1.9 Proc jest Proc # curry, który pozwala zamienić Proc przyjmujący n argumentów na taki, który akceptuje n-1. Tutaj jest połączony z poradą Proc # ===, o której wspomniałem powyżej:
źródło
Operatory logiczne na wartościach innych niż boolowskie.
&&
i||
Oba zwracają wartość ostatniego ocenianego wyrażenia.
Dlatego też
||=
zaktualizuje zmienną z wyrażeniem zwracanej wartości po prawej stronie, jeśli zmienna jest niezdefiniowana. Nie jest to wyraźnie udokumentowane, ale powszechnie wiadomo.Jednak
&&=
nie jest to tak powszechnie znane.jest równa
Jest to bardzo przydatne w przypadku destrukcyjnych operacji, które nie powinny być kontynuowane, jeśli zmienna jest niezdefiniowana.
źródło
string &&= string + "suffix"
jest równoważnestring = string && string + "suffix"
. To&&
i||
zwrot ich drugiego argumentu omówiono w PickAx, str. 154 (Część I - Aspekty języka Ruby, wyrażenia, wykonywanie warunkowe).Funkcja Symbol # to_proc dostarczana przez Railsy jest naprawdę fajna.
Zamiast
Możesz pisać:
źródło
require 'activesupport'
ponieważ tak naprawdę pochodzi większość tych pomocników.I ostatnia - w ruby możesz użyć dowolnego znaku, który chcesz oddzielić ciągi. Weź następujący kod:
Jeśli nie chcesz usuwać podwójnych cudzysłowów w ciągu, możesz po prostu użyć innego separatora:
Oprócz uniknięcia konieczności zmiany miejsca na separatory, możesz użyć tych separatorów dla ładniejszych ciągów wielowierszowych:
źródło
Uważam, że użycie polecenia define_method do dynamicznego generowania metod jest dość interesujące i niezbyt dobrze znane. Na przykład:
Powyższy kod używa polecenia „define_method” do dynamicznego tworzenia metod od „press1” do „press9”. Zamiast wpisywać wszystkie 10 metod, które zasadniczo zawierają ten sam kod, do generowania tych metod w locie w razie potrzeby używane jest polecenie define method.
źródło
Użyj obiektu Range jako nieskończonej leniwej listy:
Więcej informacji tutaj: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
źródło
moduł_funkcja
Metody modułu, które są zadeklarowane jako module_function utworzą swoje kopie jako metody wystąpienia prywatnego w klasie zawierającej Module:
Jeśli użyjesz module_function bez żadnych argumentów, wówczas wszelkie metody modułu, które pojawią się po instrukcji module_function, same staną się automatycznie module_functions.
źródło
module_function
(drugi sposób) jest po prostu użycieextend self
(co wygląda całkiem nieźle: D)Krótkie wstrzyknięcie, takie jak:
Suma zakresu:
źródło
require 'backports'
:-)Uwaga: ten przedmiot został uznany za # 1 najbardziej przerażającego hacka 2008 roku , więc używaj go ostrożnie. Właściwie unikaj tego jak zarazy, ale z pewnością jest to Ukryty Rubin.
Superators Dodają nowych operatorów do Rubiego
Czy kiedykolwiek chciałeś mieć super tajnego operatora uzgadniania do jakiejś unikalnej operacji w swoim kodzie? Lubisz grać w code-golfa? Wypróbuj operatory, takie jak - ~ + ~ - lub <--- Ten ostatni jest używany w przykładach do odwracania kolejności elementów.
Nie mam nic wspólnego z projektem Superators poza podziwianiem go.
źródło
Spóźniłem się na imprezę, ale:
Możesz łatwo wziąć dwie tablice o równej długości i przekształcić je w skrót, w którym jedna tablica dostarcza klucze, a druga wartości:
(Działa to, ponieważ Array # zip „spakuje” wartości z dwóch tablic:
Hash [] może przyjąć właśnie taką tablicę. Widziałem, jak ludzie też to robią:
Co daje ten sam wynik, ale splatanie i spłaszczanie są całkowicie niepotrzebne - być może nie były w przeszłości?)
źródło
Automatyczne ożywianie skrótów w Rubim
To może być po prostu cholernie przydatne.
źródło
module InfHash; def self.new; Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}; end; end
Destrukturyzacja tablicy
Gdzie:
Używając tej techniki, możemy użyć prostego przypisania, aby uzyskać dokładne wartości, które chcemy z zagnieżdżonej tablicy o dowolnej głębokości.
źródło
Class.new()
Utwórz nową klasę w czasie wykonywania. Argumentem może być klasa, z której ma pochodzić, a blok jest treścią klasy. Możesz również sprawdzić, czy
const_set/const_get/const_defined?
twoja nowa klasa została poprawnie zarejestrowana, tak abyinspect
wypisała nazwę zamiast numeru.Nie jest to coś, czego potrzebujesz na co dzień, ale całkiem przydatne, kiedy to robisz.
źródło
MyClass = Class.new Array do; def hi; 'hi'; end; end
wydaje się być równoważneclass MyClass < Array; def hi; 'hi'; end; end
.utwórz tablicę kolejnych liczb:
ustawia x na [0, 1, 2, 3, 4, 5]
źródło
*
) w zasadzie ito_a
tak wywołuje .Wiele magii, które widzisz w Rubyland, ma związek z metaprogramowaniem, czyli po prostu pisaniem kodu, który pisze kod za Ciebie. Ruby's
attr_accessor
,attr_reader
iattr_writer
są prostym metaprogramowaniem, ponieważ tworzą dwie metody w jednej linii, według standardowego wzorca. Railsy wykonują bardzo dużo metaprogramowania za pomocą metod zarządzania relacjami, takich jakhas_one
ibelongs_to
.Ale tworzenie własnych sztuczek metaprogramowania za pomocą
class_eval
do wykonywania dynamicznie napisanego kodu jest całkiem proste .Poniższy przykład umożliwia obiektowi opakowania przekazywanie pewnych metod do obiektu wewnętrznego:
Metoda
Wrapper.forwards
przyjmuje symbole dla nazw metod i przechowuje je wmethods
tablicy. Następnie, dla każdego z podanych,define_method
tworzymy nową metodę, której zadaniem jest przesłanie wiadomości wraz ze wszystkimi argumentami i blokami.Świetnym źródłem informacji na temat zagadnień związanych z metaprogramowaniem jest „ Why the Lucky Stiff” „Seeing Metaprogramming Clearly” .
źródło
użyj wszystkiego, na co odpowiada, do
===(obj)
porównań przypadków:Module
(a więcClass
)Regexp
,Date
i wiele innych klas określić metodą przykład: === (drugiego), i wszystkie mogą być użyte.Podziękowania dla Farrela za przypomnienie o
Proc#call
aliasie jakProc#===
w Rubim 1.9.źródło
Binarny "ruby" (przynajmniej MRI) obsługuje wiele przełączników, które sprawiły, że jednolinijkowe perl stały się dość popularne.
Istotne:
put
s na końcu każdej iteracji pętliKilka przykładów:
Zapraszam do wygooglowania „ruby one-liners” i „perl one-liners”, aby uzyskać więcej użytecznych i praktycznych przykładów. Zasadniczo pozwala ci używać ruby jako dość potężnego zamiennika awk i sed.
źródło
Metoda send () jest metodą ogólnego przeznaczenia, której można użyć w dowolnej klasie lub obiekcie w Rubim. Jeśli nie jest zastępowany, funkcja send () akceptuje ciąg znaków i wywołuje nazwę metody, której ciąg jest przekazywany. Na przykład, jeśli użytkownik kliknie przycisk „Clr”, ciąg „press_clear” zostanie wysłany do metody send () i zostanie wywołana metoda „press_clear”. Metoda send () pozwala na przyjemny i dynamiczny sposób wywoływania funkcji w Rubim.
Więcej o tej funkcji mówię w Blogging Shoes: The Simple-Calc Application
źródło
Oszukać jakąś klasę lub moduł, mówiąc, że wymagał czegoś, czego tak naprawdę nie wymagał:
Jest to przydatne na przykład, gdy wymagamy A, które z kolei wymaga B, ale nie potrzebujemy B w naszym kodzie (a A nie użyje go również w naszym kodzie):
Na przykład Backgroundrb
bdrb_test_helper requires
'test/spec'
, ale w ogóle go nie używasz, więc w swoim kodzie:źródło
Fixnum#to_s(base)
może być naprawdę przydatna w niektórych przypadkach. Jednym z takich przypadków jest generowanie losowych (pseudo) unikalnych tokenów poprzez konwersję liczby losowej na ciąg przy użyciu podstawy 36.Żeton o długości 8:
Żeton o długości 6:
źródło
Zdefiniowanie metody, która akceptuje dowolną liczbę parametrów i po prostu odrzuca je wszystkie
Powyższa
hello
metoda musi tylko pojawić sięputs
"hello"
na ekranie i wywołaćsuper
- ale ponieważ nadklasahello
definiuje również parametry - jednak ponieważ w rzeczywistości nie musi używać samych parametrów - nie musi nadawać im nazwy.źródło