A partir de um arquivo incluído, como posso obter o nome do arquivo do arquivo fazendo o incluindo?

9

Desculpas pelo título de pergunta mal formulado - não tenho ideia de como colocá-lo melhor!

No código a seguir, quando executo ruby bar.rb , como posso gerar bar.rb em vez de foo.rb ?

Em foo.rb :

module Foo
  def filename
    __FILE__
  end
end

Em bar.rb :

require_relative 'foo'
include Foo

puts filename # outputs 'foo.rb'

Isto é para uma função de biblioteca que, cada vez que algum código é executado, registra a localização (e git ref) desse código.

    
por seb 15.10.2012 в 13:35
fonte

2 respostas

4

Sua pergunta me estimulou a abrir a fonte do interpretador Ruby e ver como __FILE__ realmente funciona. A resposta é bem interessante: é implementada dentro do analisador. O lexer tem um tipo de token especial para __FILE__ . Quando o analisador vê esse token, ele o converte em uma constante de string, que contém o nome do arquivo no qual o analisador está trabalhando.

Da linha 14948 do ext / ripper / ripper.c:

case keyword__FILE__:
return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
                        rb_filesystem_encoding()));

Acho que isso deve deixar claro que tentar fazer com que __FILE__ retorne o nome do arquivo incluído é completamente impossível, a menos que você invada a fonte do interpretador Ruby ou escreva seu próprio pré-processador, que transforma __FILE__ em outra coisa antes passando a fonte Ruby para o intérprete!

    
por Alex D 15.10.2012 / 17:05
fonte
1

Existe um truque que você pode usar. Se você passar um bloco para o método, você pode usar o fechamento de blocos para determinar sua origem. Algo como:

def filename(&blk)
  blk.eval "__FILE__"
end

Mas, novamente, isso significa que você precisa passar por um bloco.

Honestamente, eu me pergunto o que você está tentando realizar, b / c fora de fazer algum método comum de extensão do núcleo, isso é provavelmente algo que você realmente não quer fazer.

    
por trans 21.10.2012 / 14:36
fonte