O que significa 'require: false' no Gemfile?

429

Faz isso:

gem 'whenever', require: false

significa que a gema precisa ser instalada ou significa que não é necessária?

rafamvc
fonte
1
A maioria das respostas (incluindo a aceita) refere-se ao Rails, que Bundler.requirepor padrão é o que eu entendo. Apenas as respostas de Ciro e Nesha estão corretas.
Nakilon

Respostas:

472

Isso significa instalar a gema, mas não é necessário exigir quando você inicia o Bundler. Então, você precisará ligar manualmente

require "whenever"

se você quiser usar a biblioteca.

Se você fosse fazer

gem "whenever", require: "whereever"

o bundler baixaria a gema chamada sempre, mas chamaria

require "whereever"

Isso geralmente é usado se o nome da biblioteca a exigir for diferente do nome da gema.

Rob Di Marco
fonte
112
@VenkatD. Às vezes, você deseja instalar certas gemas, mas não deseja carregá-las em todos os processos. Eu tenho uma tarefa específica de rake que desejo invocar periodicamente no Heroku por meio do complemento agendado. Essa tarefa de rake em particular requer certas gemas que o restante do aplicativo não precisa. Então, eu :require => falseessas gemas específicas e explicitamente a require "thegem"partir da tarefa rake. Isso economizaria memória nos processos principais do aplicativo e no tempo de inicialização, etc. O desempenho do aplicativo, no entanto, não deve ser afetado, mesmo se você precisar dessas gemas adicionais em cada processo.
Michael van Rooijen
5
@MichaelvanRooijen - grandes pontos, no entanto: "O desempenho do aplicativo, no entanto, não deve ser afetado, mesmo se você precisar dessas gemas adicionais em todos os processos". Eu não acho que seja verdade. Objetos alocando dá trabalho, e o GC tem que correr através de todos eles cada vez, para mais = mais lento, de acordo com confreaks.com/videos/2668-gogaruco2013-measuring-ruby
Nathan Long
1
@ MichaelvanRooijen - Na prática, você está certo, isso geralmente não importa, a menos que você use a biblioteca. Mas exigir uma jóia, pelo menos, carregará seu arquivo principal na lib, e provavelmente requer mais. Mesmo se você require 'yaml'tiver agora o YAMLmódulo como um objeto na memória.
Nathan Long
2
E se você deseja definir Exigir como false e o nome da biblioteca também é diferente do nome da gema?
Peter-Jan Celis
2
@ Peter-JanCelis Nesse caso, você apenas definiria :require => falsee, em seguida, no seu código teria umrequire 'library_name_here'
Rob Di Marco
73

Você usa :require => falsequando deseja que a gema seja instalada, mas não "necessária".

Portanto, no exemplo que você deu: gem 'whenever', :require => false quando alguém executa o pacote, instale o gem sempre que ele estiver instalado como em gem install whenever. Sempre que é usado para criar tarefas cron executando uma tarefa rake, mas geralmente não é usado no aplicativo rails (ou em outra estrutura, se não no rails).

Portanto, você pode usar :require => falsepara qualquer coisa que precise executar a partir da linha de comando, mas não precisa dentro do seu código.

gduq
fonte
6
Isso também pode ser usado para uma gema que você usa apenas em um pequeno subconjunto de solicitações.
Nathan Long
61

require: falsediz Bundler.requirepara não exigir essa gema específica: a gema deve ser solicitada explicitamente via require 'gem'.

Esta opção não afeta:

  • bundle install: a gema será instalada independentemente

  • a requireconfiguração do caminho de pesquisa pelo bundler.

    O Bundler adiciona coisas ao caminho quando você faz um dos seguintes:

    • Bundle.setup
    • que é chamado por require bundler/setup
    • que é chamado por bundle exec

Exemplo

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

Em seguida, o seguinte não gerará exceções:

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

No GitHub para você brincar com ele.

Uso de trilhos

Conforme explicado no tutorial de inicialização , o modelo padrão do Rails é executado na inicialização:

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

config/boot.rb contém:

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

que faz require 'bundler/setup'e configura o caminho requerido.

config/application.rb faz:

Bundler.require(:default, Rails.env)

o que realmente requer as gemas.

Ciro Santilli adicionou uma nova foto
fonte
Observe que o uso require 'fakerpode não usar a versão correta da gema, especificamente se você é o Gemfile e aponta para uma referência git.
Dazonic 2/10
@dazonic Haml é diferente no exemplo?
Ciro Santilli #
9

Sempre que você especificar uma Gem no seu Gemfilee executar bundle install, o bundler instalará o gem especificado e carregará o código para esse Gem no seu aplicativo, require 'whenever'dessa maneira, o bundler carregará o código de todas as suas Gems no seu aplicativo Rails e você poderá chamar qualquer método de qualquer gema sem dor, como você faz na maioria das vezes.

mas Gems como whenever, faker or capistrano são algo que você não precisa no código do aplicativo, sempre que precisar no código do schedule.rb arquivo para gerenciar crons e capistrano no deploy.rb arquivo para personalizar a receita de implantação, para que você não precise carregar o código dessas gemas no código do aplicativo e onde quer que esteja Se você quiser chamar qualquer método dessas gemas, poderá solicitá-las manualmente colocando-as require "whenever" . para que você coloque :require => falseseu Gemfile para essas gemas, dessa maneira o empacotador instalará essa gema, mas não carregará o código dessa gema, você poderá fazê-lo sempre que quiser, simplesmente colocando como exigir 'sempre' no seu caso.

Subhash Chandra
fonte
2

Para solicitar gemas no seu Gemfile, você precisará ligar Bundler.require.

Você pode impedir que o bundler exija a gema require: false, mas ela ainda instalará e manterá a gema. Verifique isso para uma explicação mais detalhada.

Nesha Zoric
fonte