Was bedeutet "erfordern: falsch" in Gemfile?

428

Macht dies:

gem 'whenever', require: false

bedeutet, dass der Edelstein installiert werden muss, oder bedeutet dies, dass er nicht benötigt wird?

rafamvc
quelle
1
Die meisten Antworten (einschließlich der akzeptierten) beziehen sich auf Rails, die Bundler.requirenach meinem Verständnis standardmäßig ausgeführt werden. Nur die Antworten von Ciro und Nesha sind richtig.
Nakilon

Antworten:

472

Dies bedeutet, dass Sie den Edelstein installieren, aber beim Starten von Bundler nicht erforderlich aufrufen müssen. Sie müssen also manuell anrufen

require "whenever"

wenn Sie die Bibliothek nutzen möchten.

Wenn du es tun würdest

gem "whenever", require: "whereever"

dann würde der Bundler den genannten Edelstein jederzeit herunterladen, aber anrufen

require "whereever"

Dies wird häufig verwendet, wenn sich der Name der gewünschten Bibliothek vom Namen des Edelsteins unterscheidet.

Rob Di Marco
quelle
112
@ VenkatD. Manchmal möchten Sie bestimmte Edelsteine ​​installieren, aber Sie möchten sie nicht in jeden Prozess laden. Ich habe eine bestimmte Rechenaufgabe, die ich regelmäßig über das planmäßige Add-On für Heroku aufrufen möchte. Diese spezielle Rechenaufgabe erfordert bestimmte Edelsteine, die der Rest der Anwendung nicht benötigt. Also ich :require => falsediese besonderen Edelsteine ​​und explizit require "thegem"von der Rechenaufgabe. Dies würde dann Speicher in den Haupt-App-Prozessen und in der Startzeit usw. sparen. Die App-Leistung sollte jedoch nicht beeinträchtigt werden, selbst wenn Sie diese zusätzlichen Juwelen in jedem Prozess benötigen.
Michael van Rooijen
5
@MichaelvanRooijen - tolle Punkte jedoch: "Die App-Leistung sollte jedoch nicht beeinträchtigt werden, selbst wenn Sie diese zusätzlichen Edelsteine ​​in jedem Prozess benötigen." Ich denke nicht, dass das stimmt. Das Zuweisen von Objekten erfordert Arbeit, und der GC muss jedes Mal alle durchlaufen, also mehr = langsamer, laut confreaks.com/videos/2668-gogaruco2013-measuring-ruby
Nathan Long
1
@MichaelvanRooijen - In der Praxis haben Sie Recht, es spielt im Allgemeinen keine Rolle, wenn Sie die Bibliothek nicht verwenden. Wenn Sie jedoch einen Edelstein benötigen, wird zumindest seine Hauptdatei in lib geladen, und wahrscheinlich erfordert er mehr für sich. Selbst wenn Sie require 'yaml', haben Sie jetzt das YAMLModul als Objekt im Speicher.
Nathan Long
2
Was ist, wenn Sie require auf false setzen möchten und der Bibliotheksname sich auch vom Edelsteinnamen unterscheidet?
Peter-Jan Celis
2
@ Peter-JanCelis In diesem Fall würden Sie nur setzen :require => falseund dann in Ihrem Code einerequire 'library_name_here'
Rob Di Marco
73

Sie verwenden, :require => falsewenn der Edelstein installiert, aber nicht "erforderlich" sein soll.

In dem Beispiel, das Sie gegeben haben: gem 'whenever', :require => false Wenn jemand eine Bundle-Installation ausführt, wird das Wann-Gem wie bei installiert gem install whenever. Wann immer Cron-Jobs durch Ausführen einer Rake-Task erstellt werden, wird dies normalerweise nicht in der Rails-Anwendung (oder einem anderen Framework, wenn nicht Rails) verwendet.

Sie können also :require => falsealles verwenden, was Sie über die Befehlszeile ausführen müssen, aber nicht in Ihrem Code benötigen.

gduq
quelle
6
Dies kann auch für einen Edelstein verwendet werden, den Sie nur in einer kleinen Teilmenge von Anforderungen verwenden.
Nathan Long
61

require: falsesagt Bundler.require, dass dieser bestimmte Edelstein nicht benötigt werden soll: Der Edelstein muss explizit über benötigt werden require 'gem'.

Diese Option hat keine Auswirkungen auf:

  • bundle install: Der Edelstein wird trotzdem installiert

  • der requirevom Bundler eingerichtete Suchpfad.

    Bundler fügt dem Pfad Dinge hinzu, wenn Sie eine der folgenden Aktionen ausführen:

    • Bundle.setup
    • welches von genannt wird require bundler/setup
    • welches von genannt wird bundle exec

Beispiel

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

Dann werden die folgenden Ausnahmen nicht ausgelöst:

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

Auf GitHub kannst du damit spielen.

Schienengebrauch

Wie im Initialisierungs-Tutorial erläutert , wird die Standard-Rails-Vorlage beim Start ausgeführt:

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

config/boot.rb enthält:

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

Das macht das require 'bundler/setup'und richtet den erforderlichen Pfad ein.

config/application.rb tut:

Bundler.require(:default, Rails.env)

was eigentlich die Edelsteine ​​erfordert.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
Beachten Sie, dass bei Verwendung require 'fakermöglicherweise nicht die richtige Gem-Version verwendet wird, insbesondere wenn Sie Gemfile-Punkte auf eine Git-Referenz verweisen.
Dazonic
@dazonic ist Haml anders im Beispiel?
Ciro Santilli 法轮功 冠状 病 六四 事件 2
9

Immer wenn Sie einen Edelstein in Ihrer App angeben Gemfileund ausführen bundle install, installiert der Bundler den angegebenen Edelstein und lädt den Code für diesen Edelstein in Ihrer App. Auf require 'whenever'diese Weise lädt der Bundler den Code für alle Ihre Edelsteine ​​in Ihre Rails-App, und Sie können eine beliebige Methode aufrufen von jedem Edelstein ohne Schmerzen, wie Sie es die meiste Zeit tun.

Aber Gems wie whenever, faker or capistrano sind etwas, das Sie in Ihrem App-Code nicht benötigen. Sie benötigen immer dann Code in Ihrer schedule.rb Datei, um Crones und Capistrano-Code in der deploy.rb Datei zu verwalten, um das Bereitstellungsrezept anzupassen, sodass Sie keinen Code für diese Gems in Ihren App-Code laden müssen und wo immer Sie möchten Wenn Sie eine Methode aus diesen Edelsteinen aufrufen möchten, können Sie diese Edelsteine ​​manuell selbst durch Putten anfordern require "whenever" . :require => falseWenn Sie also Ihre Gem-Datei für diese Gems eingeben, installiert der Bundler diesen Gem, lädt jedoch keinen Code für diesen Gem selbst. Sie können dies tun, wann immer Sie möchten, indem Sie in Ihrem Fall einfach "require" "when" eingeben.

Subhash Chandra
quelle
2

Um Edelsteine ​​in Ihrer Gemfile zu benötigen, müssen Sie anrufen Bundler.require.

Sie können verhindern, dass der Bundler den Edelstein mit benötigt, der Edelstein require: falsewird jedoch weiterhin installiert und gewartet. Überprüfen Sie dieses heraus für eine ausführlichere Erklärung.

Nesha Zoric
quelle