If __FILE_ == $0 executed twice

Hello,

As recommended in the pickaxe I often have a section at the end of a
.rb file with
if __FILE__ == $0
....
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
Is there a reasonable workaround for this ?

Cheers,

Han Holl

My apologies for answering myself, but I've discovered that
if __FILE__ == $0 and caller(0).size == 1
does what I want.

More elegant suggestions remain welcome of course.

Cheers,

Han Holl

···

On 5/24/05, Han Holl <han.holl@gmail.com> wrote:

Hello,

As recommended in the pickaxe I often have a section at the end of a
.rb file with
if __FILE__ == $0
....
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
Is there a reasonable workaround for this ?

Cheers,

Han Holl

Are you using 'load' or 'require'?

···

On May 24, 2005, at 3:19 AM, Han Holl wrote:

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
Is there a reasonable workaround for this ?

i have code generators for 'serious' lib files that do this:

   unless defined? $__foo_bar__
     module Foo
   #--{{{
       Foo::LIBDIR = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR unless
         defined? Foo::LIBDIR

       class Bar
   #--{{{
   #--}}}
       end # class Bar
   #--}}}
     end # module Foo
   $__foo_bar__ = __FILE__
   end

it's the 'unless defined?' bit that's imortant here, so something like:

   unless defined? $__foo_main__

   module Foo
     class Main
     end
   end

   Foo::Main::new(ARGV).run if $0 == __FILE__

   $__foo_main__ = __FILE__
   end

will do the trick. the reason it happens is that

   require 'a.rb' # loads file

and

   require './a.rb' # loads file

because require doesn't do a File::expand_path on loaded features. imho it's
a bug and require should actually hash the stat of the file to see if it's
loaded but that explodes on nfs sometimes... at least expanding the path would
help though.

cheers.

-a

···

On Tue, 24 May 2005, Han Holl wrote:

Hello,

As recommended in the pickaxe I often have a section at the end of a
rb file with
if __FILE__ =3D=3D $0
...
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
Is there a reasonable workaround for this ?

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

Hi,

···

Am Dienstag, 24. Mai 2005, 18:19:37 +0900 schrieb Han Holl:

As recommended in the pickaxe I often have a section at the end of a
.rb file with
if __FILE__ == $0
....
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.

Not here. What is your output of this:

--------------------
def gen prg, oth
  name = "#{prg}.rb"
  File.open name, "w" do |f|
    f.puts <<HERE
require "#{oth}"

puts [ __FILE__, $0].inspect

if __FILE__ == $0 then
  puts "Hello, here is `#{prg}'."
end
HERE
    name
  end
end

names = [ "a", "b"]

a, b = gen( *names), gen( *names.reverse)
system "ruby #{a}"
--------------------

Here (Debian Linux):

--------------------
["/home/user/tmp/ruby/a.rb", "a.rb"]
["/home/user/tmp/ruby/b.rb", "a.rb"]
["a.rb", "a.rb"]
Hello, here is `a'.
--------------------

Which OS are you working under?

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Han Holl wrote:

Hello,

As recommended in the pickaxe I often have a section at the end of a
rb file with
if __FILE__ == $0
...
end

Out of curiosity, where is this mentioned in the Pickaxe? I don't
remember seeing it.

require. The initial ruby file does not wind up in $"

Han

···

On 5/24/05, Gavin Kistner <gavin@refinery.com> wrote:

On May 24, 2005, at 3:19 AM, Han Holl wrote:
> However, if one of the included files includes this file itself (not
> unlikely at all), the code gets executed twice.
> Is there a reasonable workaround for this ?

Are you using 'load' or 'require'?

Yes, I also find this strange. $0 should also be included. Maybe
require could even hash on a md5sum of the contents of the file ?

Han Holl

···

On 5/24/05, Ara.T.Howard@noaa.gov <Ara.T.Howard@noaa.gov> wrote:

[ cut ]
because require doesn't do a File::expand_path on loaded features. imho it's
a bug and require should actually hash the stat of the file to see if it's
loaded but that explodes on nfs sometimes... at least expanding the path would
help though.

Hi,

At Tue, 24 May 2005 23:20:37 +0900,
Ara.T.Howard@noaa.gov wrote in [ruby-talk:143540]:

because require doesn't do a File::expand_path on loaded features.

1.9 does.

···

--
Nobu Nakada

Another note along this line...I unintentionally discovered the other day that on Windows require is case sensative while the file system is not. require "Foo" and require "foo" will cause the same file to be executed twice.

···

Ara.T.Howard@noaa.gov wrote:

On Tue, 24 May 2005, Han Holl wrote:

Hello,

As recommended in the pickaxe I often have a section at the end of a
rb file with
if __FILE__ =3D=3D $0
...
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
Is there a reasonable workaround for this ?

i have code generators for 'serious' lib files that do this:

  unless defined? $__foo_bar__
    module Foo
  #--{{{
      Foo::LIBDIR = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR unless
        defined? Foo::LIBDIR

      class Bar
  #--{{{
  #--}}}
      end # class Bar
  #--}}}
    end # module Foo
  $__foo_bar__ = __FILE__
  end

it's the 'unless defined?' bit that's imortant here, so something like:

  unless defined? $__foo_main__

  module Foo
    class Main
    end
  end

  Foo::Main::new(ARGV).run if $0 == __FILE__

  $__foo_main__ = __FILE__
  end

will do the trick. the reason it happens is that

  require 'a.rb' # loads file

and

  require './a.rb' # loads file

because require doesn't do a File::expand_path on loaded features. imho it's
a bug and require should actually hash the stat of the file to see if it's
loaded but that explodes on nfs sometimes... at least expanding the path would
help though.

cheers.

-a

p. 337

Hi Bertram,

This had my puzzled for a while, until I added '#!/usr/bin/ruby' to
a.rb, and made it executable.
Then ./a.rb produced:
["./a.rb", "./a.rb"]
Hello, here is `a'.
["./b.rb", "./a.rb"]
["./a.rb", "./a.rb"]
Hello, here is `a'.

Cheers,

Han Holl

···

On 5/24/05, Bertram Scharpf <lists@bertram-scharpf.de> wrote:

Hi,

Am Dienstag, 24. Mai 2005, 18:19:37 +0900 schrieb Han Holl:
> As recommended in the pickaxe I often have a section at the end of a
> .rb file with
> if __FILE__ == $0
> ....
> end
>
> However, if one of the included files includes this file itself (not
> unlikely at all), the code gets executed twice.

Not here. What is your output of this:

--------------------
def gen prg, oth
  name = "#{prg}.rb"
  File.open name, "w" do |f|
    f.puts <<HERE
require "#{oth}"

puts [ __FILE__, $0].inspect

if __FILE__ == $0 then
  puts "Hello, here is `#{prg}'."
end
HERE
    name
  end
end

names = [ "a", "b"]

a, b = gen( *names), gen( *names.reverse)
system "ruby #{a}"
--------------------

Here (Debian Linux):

--------------------
["/home/user/tmp/ruby/a.rb", "a.rb"]
["/home/user/tmp/ruby/b.rb", "a.rb"]
["a.rb", "a.rb"]
Hello, here is `a'.
--------------------

Which OS are you working under?

Bertram

it just keeps gettin better! :wink:

-a

···

On Wed, 25 May 2005, nobuyoshi nakada wrote:

Hi,

At Tue, 24 May 2005 23:20:37 +0900,
Ara.T.Howard@noaa.gov wrote in [ruby-talk:143540]:

because require doesn't do a File::expand_path on loaded features.

1.9 does.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

Does it also put $0 in $" ?
That would solve my problem.

Han Holl

···

On 5/25/05, nobuyoshi nakada <nobuyoshi.nakada@ge.com> wrote:

Hi,

At Tue, 24 May 2005 23:20:37 +0900,
Ara.T.Howard@noaa.gov wrote in [ruby-talk:143540]:
> because require doesn't do a File::expand_path on loaded features.

1.9 does.

Hi,

···

Am Mittwoch, 25. Mai 2005, 19:28:57 +0900 schrieb Han Holl:

On 5/24/05, Bertram Scharpf <lists@bertram-scharpf.de> wrote:
> Am Dienstag, 24. Mai 2005, 18:19:37 +0900 schrieb Han Holl:
> > As recommended in the pickaxe I often have a section at the end of a
> > .rb file with
> > if __FILE__ == $0
> > ....
> > end
> >
> Hello, here is `a'.
> --------------------
> Which OS are you working under?

This had my puzzled for a while, until I added '#!/usr/bin/ruby' to
a.rb, and made it executable.
Then ./a.rb produced:
["./a.rb", "./a.rb"]
Hello, here is `a'.
["./b.rb", "./a.rb"]
["./a.rb", "./a.rb"]
Hello, here is `a'.

Still not here. Under which circumstances do you execute?
Me: 1.8.2 apt and 1.9 self-compiled, Debian.

Just curious.

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Another note along this line...I unintentionally discovered the other day that on Windows require is case sensative while the file system is not. require "Foo" and require "foo" will

..unless you turn on case sensitivity..

cause the same file to be executed twice.

Thanks

Michal Suchanek

···

On 25. May 2005, at 5:48, Robert Peacock wrote:

Hi,

At Wed, 25 May 2005 19:51:14 +0900,
Han Holl wrote in [ruby-talk:143604]:

Does it also put $0 in $" ?

No, $0 isn't required.

That would solve my problem.

Why not move the `if' block to another file (with no suffix), like
irb for instance?

···

--
Nobu Nakada

I don't understand that at all. Both on FC3 (standard FC3 ruby) and on
RH9 (ruby-1.8.2-26 from Ian Macdonald) I get 'Hello, here is `a'.'
twice.
It makes a difference whether you run 'ruby a.rb' or './a.rb'.

Cheers,

Han Holl

···

On 5/26/05, Bertram Scharpf <lists@bertram-scharpf.de> wrote:

Still not here. Under which circumstances do you execute?
Me: 1.8.2 apt and 1.9 self-compiled, Debian.

Just curious.

Bertram

Under the if are mostly tests. The files are meant as libraries. It's
nice to have the tests nearby, and not in a seperate file.

Is there a reason why $0 is not required ? It seems a logical thing to do.
Would it break things ?
Just curious.

Cheers

Han Holl

···

On 5/25/05, nobuyoshi nakada <nobuyoshi.nakada@ge.com> wrote:

Hi,

At Wed, 25 May 2005 19:51:14 +0900,
Han Holl wrote in [ruby-talk:143604]:
> Does it also put $0 in $" ?

No, $0 isn't required.

> That would solve my problem.

Why not move the `if' block to another file (with no suffix), like
irb for instance?

Hi,

At Wed, 25 May 2005 21:55:39 +0900,
Han Holl wrote in [ruby-talk:143610]:

> Why not move the `if' block to another file (with no suffix), like
> irb for instance?
>
Under the if are mostly tests. The files are meant as libraries. It's
nice to have the tests nearby, and not in a seperate file.

Another way is put the tests after __END__ line. See
InlineTest#loadtest__END__part in test/inlinetest.rb.

Is there a reason why $0 is not required ? It seems a logical thing to do.
Would it break things ?

Till 1.8, $: includes `require'd names relative to one of $LOAD_PATH,
$0 is absolute path or relative from cwd in other hand. So comparing
$0 with $: had no meanings, however it might be in 1.9.

···

--
Nobu Nakada