Это объяснение основано на прокомментированном сценарий Ruby от моего друга. Если Вы хотите улучшить сценарий, не стесняйтесь обновлять его в ссылке.
Первый, обратите внимание, что, когда Ruby обращается к оболочке, он обычно звонит /bin/sh
, не Bash. Некоторый синтаксис Bash не поддерживается /bin/sh
во всех системах.
Вот способы выполнить сценарий оболочки:
cmd = "echo 'hi'" # Sample string that can be used
Kernel#`
, обычно называемые обратные галочки †“`cmd`
Это похоже на многие другие языки, включая Bash, PHP и Perl.
Возвраты результат команды оболочки.
Документы: http://ruby-doc.org/core/Kernel.html#method-i-60
value = `echo 'hi'`
value = `#{cmd}`
Встроенный синтаксис, %x( cmd )
После x
символ является разделителем, который может быть любым символом. Если разделитель является одним из символов (
, [
, {
, или <
, литерал состоит из символов до соответствия заключительный разделитель, принимая во внимание вложенных пар разделителя. Для всех других разделителей литерал включает символы до следующего возникновения символа-разделителя. Строковая интерполяция #{ ... }
позволяется.
Возвраты результат команды оболочки, точно так же, как обратные галочки.
Документы: http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
value = %x( echo 'hi' )
value = %x[ #{cmd} ]
Kernel#system
Выполняет данную команду в подоболочке.
Возвраты true
, если команда была найдена и выполнена успешно, false
иначе.
Документы: http://ruby-doc.org/core/Kernel.html#method-i-system
wasGood = system( "echo 'hi'" )
wasGood = system( cmd )
Kernel#exec
Замены текущий процесс путем выполнения данной внешней команды.
Возвраты ни один, текущий процесс заменяется и никогда не продолжается.
Документы: http://ruby-doc.org/core/Kernel.html#method-i-exec
exec( "echo 'hi'" )
exec( cmd ) # Note: this will never be reached because of the line above
Вот некоторый дополнительный совет: $?
, то, которое совпадает с $CHILD_STATUS
, получает доступ к состоянию выполняемой команды последней системы, если Вы используете обратные галочки, system()
или %x{}
. Можно тогда получить доступ exitstatus
и pid
свойства:
$?.exitstatus
Для большего количества чтения см.:
I think you need to create a META-INF/services/fully.qualified.ClassName and list things there, but I don't remember the spec (JAR File Specification or this).
The Practical API design confessions of a Java architect book chapter 8 is about SPI.
The ServiceLoader might help you to list available implementations. For example with the PersistenceProvider interface:
ServiceLoader<PersistenceProvider> loader =
ServiceLoader.load(PersistenceProvider.class);
Iterator<PersistenceProvider> implementations = loader.iterator();
while(implementations.hasNext()) {
PersistenceProvider implementation = implementations.next();
logger.info("PersistenceProvider implementation: " + implementation);
}
Вы можете настроить клиентский JAR для регистрации поставщиков в блоке статического инициализатора в каком-то классе, который, как вы знаете, будет вызываться перед FooAlgorithmRegistry.getProvider ()
, что-то вроде:
static {
FooAlgorithmRegistry.registerProvider("test", new MyFooAlgorithmProvider());
}
Но может быть довольно сложно найти способ гарантировать, что это будет выполняться (статические инициализаторы гарантированно запускаются один раз и только один раз при первой загрузке класса) перед методом доступа фабрики.