if __FILE_ == $0 executed twice

H

Han Holl

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 ?

Cheers,

Han Holl
 
H

Han Holl

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

More elegant suggestions remain welcome of course.

Cheers,

Han Holl
 
G

Gavin Kistner

--Apple-Mail-2--955325359
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed

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'?

--Apple-Mail-2--955325359--
 
A

Ara.T.Howard

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
--
===============================================================================
| 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
===============================================================================
 
H

Han Holl

[ 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.
=20
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
 
B

Bertram Scharpf

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}"
 
K

Karl von Laudermann

Han said:
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.
 
A

Ara.T.Howard

Hi,

At Tue, 24 May 2005 23:20:37 +0900,


1.9 does.

it just keeps gettin better! ;-)

-a
--
===============================================================================
| 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
===============================================================================
 
H

Han Holl

Hi,
=20
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__ =3D=3D $0
....
end

However, if one of the included files includes this file itself (not
unlikely at all), the code gets executed twice.
=20
Not here. What is your output of this:
=20
--------------------
def gen prg, oth
name =3D "#{prg}.rb"
File.open name, "w" do |f|
f.puts <<HERE
require "#{oth}"
=20
puts [ __FILE__, $0].inspect
=20
if __FILE__ =3D=3D $0 then
puts "Hello, here is `#{prg}'."
end
HERE
name
end
end
=20
names =3D [ "a", "b"]
=20
a, b =3D gen( *names), gen( *names.reverse)
system "ruby #{a}"
--------------------
=20
Here (Debian Linux):
=20
--------------------
["/home/user/tmp/ruby/a.rb", "a.rb"]
["/home/user/tmp/ruby/b.rb", "a.rb"]
["a.rb", "a.rb"]
Hello, here is `a'.
--------------------
=20
Which OS are you working under?
=20
Bertram
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
 
N

nobuyoshi nakada

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?
 
H

Han Holl

Hi,
=20
At Wed, 25 May 2005 19:51:14 +0900,
Han Holl wrote in [ruby-talk:143604]:
Does it also put $0 in $" ?
=20
No, $0 isn't required.
=20
That would solve my problem.
=20
Why not move the `if' block to another file (with no suffix), like
irb for instance?
=20
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
 
B

Bertram Scharpf

Hi,

Am Mittwoch, 25. Mai 2005, 19:28:57 +0900 schrieb Han Holl:
Am Dienstag, 24. Mai 2005, 18:19:37 +0900 schrieb Han Holl:
Hello, here is `a'.

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
 
N

nobuyoshi nakada

Hi,

At Wed, 25 May 2005 21:55:39 +0900,
Han Holl wrote in [ruby-talk:143610]:
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.
 
H

Han Holl

On 5/26/05 said:
Still not here. Under which circumstances do you execute?
Me: 1.8.2 apt and 1.9 self-compiled, Debian.
=20
Just curious.
=20
Bertram
=20
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
 
H

Han Holl

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.
=20
I see. While thinking it over, I realize that there would remain a
race condition anyhow.
In other words, the code would always first be executed in the
required copy, because it cannot be put in $" until the entire file is
processed.
Maybe
if __FILE__ =3D=3D $0 and caller(0).size =3D=3D 1
isn't so bad after all.
Maybe there isn't a one-on-one replacement for Pythons=20
if __name__ =3D=3D '__main__'
after all.

Han Holl
 
M

Michal Suchanek

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top