Co oznacza „wymaga: fałsz” w Gemfile?

429

Czy to:

gem 'whenever', require: false

oznacza, że ​​klejnot musi zostać zainstalowany, czy oznacza to, że nie jest wymagany?

rafamvc
źródło
1
Większość odpowiedzi (w tym jedna zaakceptowana) dotyczy Railsów, które Bundler.requiredomyślnie wykonują, jak rozumiem. Tylko odpowiedzi Ciro i Neshy są poprawne.
Nakilon

Odpowiedzi:

472

Oznacza to, że zainstaluj klejnot, ale nie wymagaj call podczas uruchamiania Bundlera. Będziesz musiał ręcznie zadzwonić

require "whenever"

jeśli chcesz skorzystać z biblioteki.

Gdybyś miał to zrobić

gem "whenever", require: "whereever"

następnie sprzedawca pobierze klejnot o nazwie za każdym razem, ale zadzwoni

require "whereever"

Jest to często używane, jeśli nazwa wymaganej biblioteki jest inna niż nazwa klejnotu.

Rob Di Marco
źródło
112
@VenkatD. czasami chcesz zainstalować niektóre klejnoty, ale nie chcesz ich ładować do każdego procesu. Mam szczególne zadanie prowizji, które chcę okresowo wywoływać na Heroku za pomocą ich harmonogramu. To konkretne zadanie prowizji wymaga pewnych klejnotów, których reszta aplikacji nie potrzebuje. Więc ja :require => falsete szczególne klejnoty i wyraźnie require "thegem"z zadania rake. Pozwoliłoby to zaoszczędzić pamięć w głównych procesach aplikacji i czasie uruchamiania itp. Nie powinno to jednak wpływać na wydajność aplikacji, nawet jeśli potrzebujesz tych dodatkowych klejnotów w każdym procesie.
Michael van Rooijen
5
@MichaelvanRooijen - świetne punkty: „Jednak nie powinno to wpływać na wydajność aplikacji, nawet jeśli potrzebujesz tych dodatkowych klejnotów w każdym procesie”. Nie sądzę, że to prawda. Przydzielanie obiektów wymaga pracy, a GC musi je wszystkie przepuszczać za każdym razem, więc więcej = wolniej, zgodnie z confreaks.com/videos/2668-gogaruco2013-measuring-ruby
Nathan Long
1
@MichaelvanRooijen - W praktyce masz rację, na ogół nie będzie to miało znaczenia, chyba że skorzystasz z biblioteki. Ale wymaganie klejnotu przynajmniej załaduje jego główny plik do biblioteki lib i prawdopodobnie wymaga więcej. Nawet jeśli ty require 'yaml', masz teraz YAMLmoduł jako obiekt w pamięci.
Nathan Long
2
Co zrobić, jeśli chcesz ustawić opcję false, a nazwa biblioteki jest inna niż nazwa klejnotu?
Peter-Jan Celis
2
@ Peter-JanCelis W takim przypadku wystarczy ustawić, :require => falsea następnie w swoim kodzie miećrequire 'library_name_here'
Rob Di Marco
73

Używasz, :require => falsegdy chcesz zainstalować klejnot, ale nie jest on „wymagany”.

Tak więc w podanym przez ciebie przykładzie: gem 'whenever', :require => false kiedy ktoś uruchomi pakiet, zainstaluj za każdym razem, gdy klejnot zostanie zainstalowany tak jak w przypadku gem install whenever. Ilekroć jest używany do tworzenia zadań cron poprzez uruchomienie zadania prowizji, ale zwykle nie jest używany z poziomu aplikacji szyn (lub innych struktur, jeśli nie szyn).

Możesz więc używać :require => falsewszystkiego, co musisz uruchomić z wiersza poleceń, ale nie potrzebujesz tego w swoim kodzie.

gduq
źródło
6
Można to również wykorzystać do klejnotu, którego używasz tylko w niewielkim podzbiorze żądań.
Nathan Long,
61

require: falsemówi, Bundler.requireaby nie wymagać tego konkretnego klejnotu: klejnot musi być wymagany jawnie przez require 'gem'.

Ta opcja nie wpływa na:

  • bundle install: klejnot zostanie zainstalowany niezależnie

  • requireustawienie ścieżki przeszukiwania Bundler.

    Bundler dodaje rzeczy do ścieżki, gdy wykonasz jedną z następujących czynności:

    • Bundle.setup
    • który jest nazywany przez require bundler/setup
    • który jest nazywany przez bundle exec

Przykład

Gemfile

source 'https://rubygems.org'
gem 'haml'
gem 'faker', require: false

main.rb

# Fail because we haven't done Bundler.require yet.
# bundle exec does not automatically require anything for us,
# it only puts them in the require path.
begin Haml; rescue NameError; else raise; end
begin Faker; rescue NameError; else raise; end

# The Bundler object is automatically required on `bundle exec`.
Bundler.require

Haml
# Not required because of the require: false on the Gemfile.
# THIS is what `require: false` does.
begin Faker; rescue NameError; else raise; end

# Faker is in the path because Bundle.setup is done automatically
# when we use `bundle exec`. This is not affected by `require: false`.
require 'faker'
Faker

W takim przypadku następujące wyjątki nie spowodują wyjątków:

bundle install --path=.bundle
bundle exec ruby main.rb

Na GitHub możesz grać z nim.

Wykorzystanie szyn

Jak wyjaśniono w samouczku inicjalizacji , domyślny szablon Railsów jest uruchamiany podczas uruchamiania:

  • config/boot.rb
  • config/application.rb

config/boot.rb zawiera:

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

który wykonuje require 'bundler/setup'i ustawia wymaganą ścieżkę.

config/application.rb robi:

Bundler.require(:default, Rails.env)

co tak naprawdę wymaga klejnotów.

Ciro Santilli
źródło
Pamiętaj, że używanie require 'fakermoże nie używać poprawnej wersji klejnotu, szczególnie jeśli Gemfile wskazuje na ref git.
dazonic
@dazonic czy Haml jest inny na tym przykładzie?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
9

Za każdym razem, gdy określisz klejnot w swoim programie Gemfilei uruchomisz go bundle install, pakujący pójdzie i zainstaluje określony klejnot i załaduje kod dla tego klejnotu w twojej aplikacji, umieszczając w require 'whenever'ten sposób pakiet załadujący kod dla wszystkich twoich klejnotów w aplikacji Rails, i możesz wywołać dowolną metodę z dowolnego klejnotu bez bólu, tak jak robisz to przez większość czasu.

ale takie klejnoty whenever, faker or capistrano to coś, czego nie potrzebujesz w kodzie aplikacji, gdy potrzebujesz kodu w schedule.rb pliku, aby zarządzać cronami i kodem capistrano w deploy.rb pliku, aby dostosować przepis na wdrożenie, więc nie musisz ładować kodu dla tych klejnotów w kodzie aplikacji i gdziekolwiek jesteś chcesz wywołać dowolną metodę z tych klejnotów, możesz ręcznie wymagać tych klejnotów, umieszczając je require "whenever" . więc umieścisz :require => falseswój Gemfile dla tych Klejnotów, w ten sposób pakujący zainstaluje ten Klejnot, ale nie załaduje kodu dla tego Klejnotu, możesz to zrobić w dowolnym momencie, po prostu wstawiając opcję „wymagaj” w Twoim przypadku.

Subhash Chandra
źródło
2

Aby wymagać klejnotów w twoim Gemfile, musisz zadzwonić Bundler.require.

Możesz uniemożliwić bundlerowi wymaganie klejnotu require: false, ale nadal będzie go instalował i utrzymywał. Sprawdź to, aby uzyskać bardziej szczegółowe wyjaśnienie.

Nesha Zoric
źródło