Согласно кирке, расширение .rb не является обязательным. Технически это меняет значение: «require 'foo.rb'» требует foo.rb, тогда как «require 'foo'» может потребовать foo.rb, foo.so или foo.dll.
Сэм Стоукс
28
Есть тонкое замечание, чтобы не снимать расширение. Если какая-то другая часть вызовов кода требует 'foo', тогда ruby снова загрузит тот же файл, что может привести к ложным ошибкам. Я добавил свой собственный ответ, который объясняет это и показывает, как удалить расширение.
Это может быть очевидно, но стоит отметить, что для удаления .rb также потребуются любые файлы не-.rb в каталоге, что может быть нежелательно.
user2398029
10
Предложение @ PeteHodgson является неточным. Ruby's requireне смущает наличие или отсутствие .rbрасширения. Проверено на МРТ 1.8.7-p374, 2.1.5 и 2.2.0. Эта городская легенда происходит от Rails, где «умная» автозагрузка демонстрирует поведение, которое он описывает в более старых версиях (и может все еще демонстрировать его).
Шелдон
345
Если это каталог относительно файла, который требует (например, вы хотите загрузить все файлы в каталоге lib):
Вы также можете добавить все дочерние каталоги, как этоDir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
jspooner
62
Вероятно, безопаснее использовать File.join, чем делать предположения о прямом / обратном слэше:Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
Крис
6
Также есть require_relative
Мааша
30
Если вы используете> = ruby 2.0, вы можете использовать __dir__вместо File.dirname(__FILE__).
Кристиан Банкестер
3
@maasha Как вы используете, require_relativeчтобы требовать все файлы в каталоге?
Мне нужно было включить все мои модели ActiveRecord, гем require_all выяснил все зависимости и отлично их потребовал. Спасибо!
Панупан
2
@panupan Просто имейте в виду, что require_allразрешение циклических зависимостей решает проблему в вашем исходном коде: у вас есть исходные файлы Ruby, которые не требуют своих зависимостей. Это закрывает дверь при загрузке скальпеля, заставляя вас загружать все или ничего. Это не проблема в небольших библиотеках, но это решение, которое вы должны принимать осознанно.
Шелдон
Нет смысла раздувать ваше приложение гемами, которые вы можете просто заменить строкой кода. Это увеличивает время загрузки вашего приложения и вызывает больше ошибок в долгосрочной перспективе.
Если вы не удалите расширение, вам может понадобиться один и тот же файл дважды (ruby не поймет, что «foo» и «foo.rb» - это один и тот же файл). Двойной запрос одного и того же файла может привести к ложным предупреждениям (например, «предупреждение: уже инициализированная константа»).
Это действительно так? Документация гласит: функция не будет загружена, если ее имя уже отображается в $ ". Имя файла преобразуется в абсолютный путь, поэтому" require 'a'; require './a' "не будет загружать a.rb дважды. ruby-doc.org/core/classes/Kernel.html#M001418
Дерек
13
Мое тестирование показывает то же, что сказал Дерек: require "foo.rb"; require "foo";загрузится foo.rbтолько один раз.
Рене Саарсоо
@ PeteHodgson- Ты можешь это подтвердить?
Ярин
4
Нет. Ruby's requireне смущает наличие или отсутствие .rbрасширения. Протестировано на МРТ 1.8.7-p374, 2.1.5 и 2.2.0. Эта городская легенда происходит от Rails, где «умная» автозагрузка демонстрировала поведение, описанное в более старых версиях (и может все еще демонстрировать его).
Это красивый код. Мне нравится, как нет видимых блоков.
Нейт Симер,
1
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )устраняет зависимость от платформы (например, «/» или «\»). Работает хорошо. Спасибо.
Иван Блэк
30
Лучший способ - добавить каталог в путь загрузки, а затем requireуказать базовое имя каждого файла. Это потому, что вы хотите избежать случайного запроса одного и того же файла дважды - часто это не является предполагаемым поведением. Будет ли файл загружен или нет, зависит от того require, видел ли ранее переданный ему путь. Например, этот простой сеанс irb показывает, что вы можете по ошибке потребовать и загрузить один и тот же файл дважды.
Обратите внимание, что первые две строки возвращают, что trueозначает, что один и тот же файл был загружен оба раза. Когда используются пути, даже если пути указывают на одно и то же местоположение, requireон не знает, что файл уже был необходим.
Здесь вместо этого мы добавляем каталог в путь загрузки, а затем запрашиваем базовое имя каждого файла * .rb внутри.
dir ="/path/to/directory"
$LOAD_PATH.unshift(dir)Dir[File.join(dir,"*.rb")].each {|file| require File.basename(file)}
Если вам не нужно, чтобы файл требовался более одного раза, или вы просто хотите загрузить содержимое файла, возможно, loadследует использовать вместо require. В этом случае используйте load, потому что она лучше отражает то, что вы пытаетесь выполнить. Например:
Поскольку Rails.rootэто Pathnameпример, вы можете сделать это в любой среде Ruby, а не только в Rails (NB Rails.root.join('lib/ext/*.rb')читает немного лучше)
DMKE
Спасибо за рекомендацию; Я отредактировал, чтобы включить ваш комментарий.
Дэн Кон
Использование косой черты (/) для подкаталогов в Rails.root, например Rails.root.join('/lib'), не генерирует правильный путь. Я нашел, что это работает правильно:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Jignesh Gohel
@Jiggneshh Gohel Я удалил косые черты, как ты и предложил, спасибо.
Дэн Кон,
3
Я опоздал на вечеринку на несколько лет, но мне нравится это однострочное решение, которое я использовал, чтобы получить рельсы для включения всего в приложение / работники / проблемы:
ОК, но в моем примере это не так. '*' Изменяет арность на 1. Он работает как множественный вызов require_relative.
Александр
1
«*» Меняет арность на 1 - что вы имеете в виду? require_relative *Dir['*.rb']работать, если есть только один ruby-скрипт. Но если найдено несколько скриптов ruby, вы получитеrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)
Ответы:
Как насчет:
источник
require
не смущает наличие или отсутствие.rb
расширения. Проверено на МРТ 1.8.7-p374, 2.1.5 и 2.2.0. Эта городская легенда происходит от Rails, где «умная» автозагрузка демонстрирует поведение, которое он описывает в более старых версиях (и может все еще демонстрировать его).Если это каталог относительно файла, который требует (например, вы хотите загрузить все файлы в каталоге lib):
Изменить: на основе комментариев ниже, обновленная версия:
источник
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
вместоFile.dirname(__FILE__)
.require_relative
чтобы требовать все файлы в каталоге?Попробуйте гем require_all:
Это позволяет вам просто:
источник
require_all
разрешение циклических зависимостей решает проблему в вашем исходном коде: у вас есть исходные файлы Ruby, которые не требуют своих зависимостей. Это закрывает дверь при загрузке скальпеля, заставляя вас загружать все или ничего. Это не проблема в небольших библиотеках, но это решение, которое вы должны принимать осознанно.Если вы не удалите расширение, вам может понадобиться один и тот же файл дважды (ruby не поймет, что «foo» и «foo.rb» - это один и тот же файл). Двойной запрос одного и того же файла может привести к ложным предупреждениям (например, «предупреждение: уже инициализированная константа»).
источник
require "foo.rb"; require "foo";
загрузитсяfoo.rb
только один раз.require
не смущает наличие или отсутствие.rb
расширения. Протестировано на МРТ 1.8.7-p374, 2.1.5 и 2.2.0. Эта городская легенда происходит от Rails, где «умная» автозагрузка демонстрировала поведение, описанное в более старых версиях (и может все еще демонстрировать его).или, в качестве альтернативы, если вы хотите разместить файлы для загрузки в определенные папки:
объяснение:
Dir.glob принимает блок в качестве аргумента.
Метод (: require) вернет метод require.
& method (: require) преобразует метод в блок.
источник
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
устраняет зависимость от платформы (например, «/» или «\»). Работает хорошо. Спасибо.Лучший способ - добавить каталог в путь загрузки, а затем
require
указать базовое имя каждого файла. Это потому, что вы хотите избежать случайного запроса одного и того же файла дважды - часто это не является предполагаемым поведением. Будет ли файл загружен или нет, зависит от тогоrequire
, видел ли ранее переданный ему путь. Например, этот простой сеанс irb показывает, что вы можете по ошибке потребовать и загрузить один и тот же файл дважды.Обратите внимание, что первые две строки возвращают, что
true
означает, что один и тот же файл был загружен оба раза. Когда используются пути, даже если пути указывают на одно и то же местоположение,require
он не знает, что файл уже был необходим.Здесь вместо этого мы добавляем каталог в путь загрузки, а затем запрашиваем базовое имя каждого файла * .rb внутри.
Если вам не нужно, чтобы файл требовался более одного раза, или вы просто хотите загрузить содержимое файла, возможно,
load
следует использовать вместоrequire
. В этом случае используйте load, потому что она лучше отражает то, что вы пытаетесь выполнить. Например:источник
Вместо объединения путей, как в некоторых ответах, я использую
File.expand_path
:Обновить:
Вместо использования
File.dirname
вы можете сделать следующее:Где
..
полосы имя файла__FILE__
.источник
File.expand_path
Rails.root.join
ответы также работают, если вы находитесь в рельсах.Это будет работать рекурсивно на вашем локальном компьютере и удаленном компьютере (например, Heroku), который не использует относительные пути.
источник
В Rails вы можете сделать:
Обновление: исправлено с предложением @Jiggneshh Gohel для удаления слешей.
источник
Rails.root
этоPathname
пример, вы можете сделать это в любой среде Ruby, а не только в Rails (NBRails.root.join('lib/ext/*.rb')
читает немного лучше)Rails.root.join('/lib')
, не генерирует правильный путь. Я нашел, что это работает правильно:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
Я опоздал на вечеринку на несколько лет, но мне нравится это однострочное решение, которое я использовал, чтобы получить рельсы для включения всего в приложение / работники / проблемы:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
источник
А как насчет
require_relative *Dir['relative path']
?источник
require_relative *Dir['*.rb']
работать, если есть только один ruby-скрипт. Но если найдено несколько скриптов ruby, вы получитеrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)