2009-08-27 12 views
35

Tengo un script con un método de fábrica que me gustaría devolver una implementación diferente de alguna clase dependiendo de si el script se está ejecutando desde JRuby o Ruby. ¿Alguien tiene alguna idea sobre cómo puedo ver la diferencia desde el interior de mi script?¿Cómo puedo saber si estoy huyendo de JRuby vs. Ruby?

Algunas ideas iniciales que tenía eran:

  • intento de "incluye Java y rescatar de nuevo a la implementación de Ruby si falla. Este método no funciona. Ruby es lo suficientemente inteligente como para equivocarse independientemente de mi comienzo/rescate/final.

  • Haz algo tonto con ID de proceso. Prefiero evitar esto, ya que siempre se siente como un truco.

Respuesta

46

Creo que puede verificar la constante RUBY_PLATFORM.

+1

Sí. Es "java" bajo JRuby y el sistema operativo subyacente en otro lugar. – Chuck

+0

De hecho. Suficientemente bueno para mi. ¡Muchas gracias! – pastorius

+0

@Chuck: gracias por verificar. No tenía una instalación JRuby a mano. – JesperE

7

No entiendo muy bien su pregunta. Parece que estás mezclando dos niveles de abstracción completamente diferentes: Ruby es un lenguaje de programación, JRuby es un compilador del lenguaje de programación Ruby. La pregunta de si su programa se está ejecutando en Ruby o en JRuby simplemente no tiene sentido: cuando se está ejecutando en JRuby, es es que se ejecuta en Ruby, porque JRuby es una implementación de Ruby.

Es lo mismo que preguntar "¿cómo puedo saber si estoy conduciendo un Ford o un automóvil?"

Si desea saber en qué implementación de Ruby se está ejecutando, puede verificar la constante global RUBY_ENGINE. Se supone para identificar de forma única y universalmente el motor está ejecutando en adelante, aunque por desgracia no por tres razones:

  1. en algunos motores, que no lo hace lo que el motor se está ejecutando en cuentan, por ejemplo, en YARV esperaría que RUBY_ENGINE fuera 'yarv', pero en realidad es 'ruby'. Por lo tanto, falla en la parte "identificar".
  2. aún peor: en la RM, es también 'ruby', lo que significa que no sólo no le diga qué motor se están ejecutando en, pero también totalmente diferentes motores que devuelven el mismo valor . IOW, también falla en la parte "única".
  3. y por último pero no menos importante, RUBY_ENGINE es bastante nuevo, por lo que aún no es compatible con todos los motores, lo que significa que falla en la parte "universal".

Sin embargo, para sus propósitos algo así como

if defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby' 

debería funcionar bien.

+0

si está definido? RUBY_ENGINE y RUBY_ENGINE == 'jruby' –

+0

Para usar su analogía, a veces necesita saber si su automóvil es un vado. Por ejemplo, muchos necesitan saber si desea admitir una extensión nativa no compatible con jruby en su código. – Will

+0

Es bueno señalar que RUBY_ENGINE es relativamente nuevo. ¿Había una versión anterior de JRuby que no la tenía? – Trejkaz

40

Como ya se ha indicado aquí, hay varias maneras de detectar JRuby.Aquí está la lista completa, ordenadas por preferencia:

  1. simple y directa:

    RUBY_PLATFORM == "java" 
    
  2. Esto puede ser usado para otros impls también. La desventaja es que MRI 1.8.6 y 1.8.7 aún no son compatibles con RUBY_ENGINE, entonces ¿necesitamos el definido? comprobar:

    if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' 
    
  3. Si desea saber un poco más que si se trata de JRuby o no:

    if defined? JRUBY_VERSION 
    

    JRUBY_VERSION sólo se define en JRuby y proporciona el corto información de la versión, como "1.5.0.dev"

  4. La forma menos favorita: requiere 'java' o requiere 'jruby' y rescate. No debería ser usado.

+2

En realidad, debe proporcionar paréntesis para la segunda versión, por lo que sería si se define? (RUBY_ENGINE) && RUBY_ENGINE == 'jruby' –

+1

Gracias, @Tyler, de hecho, fue un error tonto, corregido! – vsizikov

+0

La última opción no es tan mala como suena. Si fueras a probar JRuby y luego requirieras 'java' de todos modos (y si no lo fue, seamos sinceros, por qué siquiera molestarnos en detectar JRuby), entonces agregar un rescate no parece tan malo. – Trejkaz

1

Si va a depurar cáscara, IRB, RVM o algún tipo de complemento como Ruby plugins editor de texto que prefieren la más prolija RUBY_DESCRIPTION.

Si usted está tratando de ejecutar un código basado en si se está ejecutando jruby o no, otras constantes comentadas son buenos: RUBY_ENGINE, JRUBY_VERSION o RUBY_PLATFORM.

Cuestiones relacionadas