Szukam bardziej eleganckiego sposobu łączenia łańcuchów w Ruby.
Mam następującą linię:
source = "#{ROOT_DIR}/" << project << "/App.config"
Czy jest na to lepszy sposób?
A jeśli o to chodzi, jaka jest różnica między <<
i +
?
ruby
string-concatenation
dagda1
źródło
źródło
Odpowiedzi:
Możesz to zrobić na kilka sposobów:
<<
ale to nie jest zwykły sposóbZ interpolacją ciągów
z
+
Druga metoda wydaje się być bardziej wydajna pod względem pamięci / prędkości od tego, co widziałem (choć nie zmierzone). Wszystkie trzy metody wygenerują niezainicjowany stały błąd, gdy parametr ROOT_DIR ma wartość zero.
W przypadku nazw ścieżek możesz użyć ich,
File.join
aby uniknąć pomieszania z separatorem nazw ścieżek.Ostatecznie jest to kwestia gustu.
źródło
+
Operator jest normalny wybór konkatenacji, a to chyba najszybszy sposób na strunach złączyć.Różnica między
+
i<<
polega na tym, że<<
zmienia obiekt po jego lewej stronie, a+
nie zmienia.źródło
+
i<<
będą o tym samym. Jeśli masz do czynienia z wieloma łańcuchami lub naprawdę dużymi, możesz zauważyć różnicę. Byłem zaskoczony, jak podobne były. gist.github.com/28953115.times do ... end
blok) dla każdego tłumacza, uzyskasz dokładniejsze wyniki. Moje testy wykazały, że interpolacja jest najszybszą metodą we wszystkich tłumaczach Ruby. Spodziewałbym<<
się, że będę najszybszy, ale dlatego porównujemy.Jeśli tylko łączysz ścieżki, możesz użyć własnej metody Ruby File.join.
źródło
z http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/
Używanie
<<
akaconcat
jest znacznie bardziej wydajne niż+=
, ponieważ ten ostatni tworzy obiekt tymczasowy i zastępuje pierwszy obiekt nowym obiektem.wynik:
źródło
Ponieważ jest to ścieżka, prawdopodobnie użyłbym tablicy i dołączył:
źródło
Oto kolejny punkt odniesienia zainspirowany tą istotą . Porównuje konkatenację (
+
), dopisywanie (<<
) i interpolację (#{}
) dla ciągów dynamicznych i predefiniowanych.wynik:
Wniosek: interpolacja w MRI jest ciężka.
źródło
Wolałbym używać Pathname:
o
<<
i+
od ruby docs:+
: Zwraca nowy ciąg zawierający other_str połączony z str<<
: Łączy dany obiekt z ul. Jeśli obiektem jest Fixnum od 0 do 255, przed konkatenacją jest on konwertowany na znak.więc różnica polega na tym, co stanie się z pierwszym operandem (
<<
dokonuje zmian w miejscu,+
zwraca nowy ciąg znaków, więc pamięć jest cięższa) i co będzie, jeśli pierwszym operandem będzie Fixnum (<<
doda, jakby to był znak z kodem równym tej liczbie,+
podniesie błąd)źródło
Pathname('/home/foo') + '/etc/passwd' # => #<Pathname:/etc/passwd>
. Jest to zgodne z projektem, opartym na przykładzie Rubydoc. Wydaje się, że File.join jest bezpieczniejszy.(Pathname(ROOT_DIR) + project + 'App.config').to_s
jeśli chcesz zwrócić obiekt typu string.Pozwól, że pokażę ci całe moje doświadczenie z tym.
Miałem zapytanie, które zwróciło 32k rekordów, dla każdego rekordu wywołałem metodę sformatowania tego rekordu bazy danych w sformatowany ciąg, a następnie powiązania go w ciąg, który pod koniec całego procesu zamieni się w plik na dysku.
Mój problem polegał na tym, że według rekordu, około 24k, proces konkatenacji Sznurka przerodził się w ból.
Robiłem to za pomocą zwykłego operatora „+”.
Kiedy zmieniłem na „<<” było jak magia. Było naprawdę szybko.
Pamiętam więc swoje stare czasy - coś w 1998 roku - kiedy używałem Javy i łączyłem String za pomocą „+” i zmieniłem z String na StringBuffer (a teraz my, deweloper Java, mamy StringBuilder).
Wierzę, że proces + / << w świecie Ruby jest taki sam jak + / StringBuilder.append w świecie Java.
Pierwszy przenosi cały obiekt w pamięci, a drugi wskazuje nowy adres.
źródło
Konkatenacja, którą mówisz? A co powiesz na
#concat
metodę?Szczerze mówiąc,
concat
jest aliasowany jako<<
.źródło
"foo" "bar" 'baz" #=> "foobarabaz"
Oto więcej sposobów na zrobienie tego:
I tak dalej ...
źródło
Możesz również użyć
%
w następujący sposób:To podejście działa również z
'
(pojedynczym) znakiem cudzysłowu.źródło
Możesz użyć
+
lub<<
operatora, ale w Ruby.concat
jest najbardziej preferowana, ponieważ jest znacznie szybsza niż inne operatory. Możesz go używać jak.źródło
.
po ostatnimconcat
nie?Sytuacja ma znaczenie, na przykład:
W pierwszym przykładzie konkatenacja z
+
operatorem nie spowoduje aktualizacjioutput
obiektu, jednak w drugim przykładzie<<
operator zaktualizujeoutput
obiekt przy każdej iteracji. Tak więc, dla powyższego rodzaju sytuacji,<<
jest lepiej.źródło
Możesz połączyć konkatenację w definicję ciągu bezpośrednio:
źródło
W twoim konkretnym przypadku możesz również użyć
Array#join
podczas konstruowania typu ścieżki pliku:Ma to przyjemny efekt uboczny polegający na automatycznej konwersji różnych typów na ciąg znaków:
źródło
Dla Puppet:
źródło