Dodawanie katalogu do $load PATH (Ruby)

Widziałem dwie powszechnie używane techniki dodawania katalogu aktualnie wykonywanego pliku do $LOAD_PATH (lub$:). Widzę zalety robienia tego na wypadek, gdybyś nie pracował z klejnotem. Jedno wydaje się bardziej gadatliwe niż drugie, oczywiście, ale czy jest powód, aby przejść z jednym nad drugim?

Pierwsza, słowna metoda (może być przesadna):

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))

I prostsze, szybkie i brudne:

$:.unshift File.dirname(__FILE__)

Każdy powód, aby przejść z jednym nad inne?

Author: Andrew Grimm, 2009-05-08

6 answers

Powiedziałbym, że należy użyć $:.unshift File.dirname(__FILE__) nad drugim, po prostu dlatego, że widziałem znacznie więcej użycia tego kodu w kodzie niż $LOAD_PATH, i jest też krótszy!

 47
Author: Ryan Bigg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 23:44:19

Ścieżka ładowania Ruby jest bardzo często zapisywana jako$:, ale to, że jest krótka, nie czyni jej lepszą. Jeśli wolisz jasność od sprytu, lub jeśli zwięzłość dla własnego dobra sprawia, że swędzi cię, nie musisz tego robić tylko dlatego, że wszyscy inni są. Przywitaj się ...

$LOAD_PATH

... i pożegnaj się ...

# I don't quite understand what this is doing...
$:
 140
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-21 21:01:50

Nie przepadam za "szybkim i brudnym" sposobem. Każdy nowy w Ruby będzie zastanawiał się, czym jest $:..

Wydaje mi się to bardziej oczywiste.
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
Albo jeśli zależy mi na pełnej ścieżce...
libdir = File.expand_path(File.dirname(__FILE__))
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

Aktualizacja 2009/09/10

Od niedawna wykonuję:

$:.unshift(File.expand_path(File.dirname(__FILE__))) unless
    $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))

Widziałem go w wielu różnych projektach ruby podczas przeglądania Githuba.

Wydaje się być konwentem?

 19
Author: Luke Antins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 16:40:14

Jeśli wpiszesz script/console w swoim projekcie Rails i wpisasz $:, otrzymasz tablicę zawierającą wszystkie katalogi potrzebne do załadowania Rubiego. Z tego małego ćwiczenia wynika, że $: jest tablicą. W związku z tym można na nim wykonywać funkcje, takie jak poprzedzanie innych katalogów metodą unshift lub operatorem <<. Jak sugerujesz w swoim oświadczeniu $: i $LOAD_PATH są takie same.

Wadą robienia tego w szybki i brudny sposób, jak wspomniałeś, jest to: jeśli masz już katalog w swojej ścieżce rozruchowej, to się powtórzy.

Przykład:

Mam wtyczkę, którą stworzyłem o nazwie todo. Mój katalog jest tak skonstruowany:

/---vendor
  |
  |---/plugins
        |
        |---/todo
              |
              |---/lib
                    |
                    |---/app
                          |
                          |---/models
                          |---/controllers
              |
              |---/rails
                    |
                    |---init.rb

W init.plik rb wpisałem następujący kod:

## In vendor/plugins/todo/rails/init.rb
    %w{ models controllers models }.each do |dir|
      path = File.expand_path(File.join(File.dirname(__FILE__), '../lib', 'app', dir))
      $LOAD_PATH << path
      ActiveSupport::Dependencies.load_paths << path
      ActiveSupport::Dependencies.load_once_paths.delete(path)
    end 

Zwróć uwagę, jak nakazuję blokowi kodu wykonywanie działań wewnątrz bloku ciągów 'models', 'controllers' i 'models', gdzie powtarzam 'models'. (FYI, %w{ ... } jest po prostu innym sposobem, aby powiedzieć Rubiemu, aby trzymał tablicę struny). Kiedy uruchamiam script/console, wpisuję:

>> puts $:

I wpisuję to, aby łatwiej było odczytać zawartość w łańcuchu. Wyjście, które otrzymuję to:

...
...
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/controllers
./Users/Me/mySites/myRailsApp/vendor/plugins/todo/lib/app/models

Jak widzisz, chociaż jest to prosty przykład, który mógłbym stworzyć podczas korzystania z projektu, nad którym obecnie pracuję, jeśli nie będziesz ostrożny, szybka i brudna droga doprowadzi do powtarzających się ścieżek. Dłuższa droga będzie sprawdzać powtarzające się ścieżki i upewnić się, że nie występują.

Jeśli jesteś doświadczonym Rails programista, prawdopodobnie masz bardzo dobre pojęcie o tym, co robisz i prawdopodobnie nie popełnisz błędu powtarzając ścieżki. Jeśli jesteś nowicjuszem, wybrałbym dłuższą drogę, dopóki nie zrozumiesz, co robisz.

 8
Author: Dyba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 16:53:16

Najlepsze, na jakie natknąłem się przy dodawaniu katalogu przez ścieżkę względną podczas korzystania z Rspec. Uważam, że jest wystarczająco gadatliwy, ale nadal jest ładny.

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
 6
Author: Dave Robertson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-05 04:09:51

Istnieje klejnot, który pozwoli Ci ustawić ścieżkę ładowania z ładniejszym i czystszym kodem. Zobacz też: https://github.com/nayyara-samuel/load-path .

Posiada również dobrą dokumentację

 1
Author: Rubyist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 01:11:21