CORE - Replace "if __FILE__ == $0" with "executed?"

The construct to detect execution of the file (in order to launch main
code) looks like this:

if FILE == $0
main
end

I would like a more elegant code.

I try to implement a method in Kernel

#myib.rb
module Kernel
def executed?
# detect in a clean way if the caller calls from an executed file
# return true if so, else return false
end
end

#maintest.rb
require ‘mylib’
if executed?
print “works nice”
else
print "seems to fail
end

What would be the code for executed?

I tried this way:
def executed?
f = eval ‘FILE’, TOPLEVEL_BINDING
p = eval ‘$0’, TOPLEVEL_BINDING
return f == p
end

but this failed somehow, and I dislike it.

.

On Thu, 2 Jun 2011 22:30:27 +0900, Ilias L. wrote:

I try to implement a method in Kernel
require ‘mylib’
f = eval ‘FILE’, TOPLEVEL_BINDING
p = eval ‘$0’, TOPLEVEL_BINDING
return f == p
end

but this failed somehow, and I dislike it.

It failed because FILE is not a constant: it is a special lexical
construct which
is replaced by just a string containing the filename at the point of
loading the file,
i.e. even before the execution begins. You simply cannot access it in
any way after the
file was loaded.

You can still implement it this way (note that it may not work on
implementations other
than MRI):

mylib.rb

module Kernel
def executed?
caller.last =~ /^(.*):\d+$/ && $0 == $1
end
end

test.rb

require ‘mylib’

if executed?
puts “Executed”
else
puts “Loaded”
end

Test it with:

$ ruby test.rb; ruby -rtest -e “”
Executed
Loaded

On Thu, Jun 02, 2011 at 10:51:46PM +0900, Peter Z. wrote:

It failed because FILE is not a constant: it is a special lexical
construct which is replaced by just a string containing the filename at
the point of loading the file, i.e. even before the execution begins.
You simply cannot access it in any way after the file was loaded.

You can still implement it this way (note that it may not work on
implementations other
than MRI):

[snip]

This seems to work just fine:

module Kernel
  def executed?
    __FILE__ == $0
  end
end

if executed?
  puts 'awesomesauce'
else
  puts 'failsauce'
end

What am I missing in the constraints of the request?

On Thu, Jun 2, 2011 at 6:34 PM, Chad P. [email protected] wrote:

if executed?
puts ‘awesomesauce’
else
puts ‘failsauce’
end

What am I missing in the constraints of the request?

He wants to have the definition of the executed? method in a different
file, which gets required in his main file, and the problem is that
FILE then it’s evaluated to the name of the other file, not the
main file.

A solution, which I don’t know if it feels clean enough would be to
pass that to the method:

#executed.rb
module Kernel
def executed? file=FILE
file == $0
end
end

#main.rb
require ‘executed’
if executed? FILE
puts “Executed”
else
puts “Loaded”
end

$ ruby main.rb
Executed
$ ruby -rmain -e “”
Loaded

Jesus.

On Fri, Jun 03, 2011 at 01:51:59AM +0900, Jess Gabriel y Galn wrote:

than MRI):

if executed?
puts ‘awesomesauce’
else
puts ‘failsauce’
end

What am I missing in the constraints of the request?

He wants to have the definition of the executed? method in a different
file, which gets required in his main file,

Ah, yeah, I apparently overlooked that. Please excuse my noise.

A solution, which I don’t know if it feels clean enough would be to
pass that to the method:

#executed.rb
module Kernel
def executed? file=FILE
file == $0
end
end

That’s pretty clever. I like it. I don’t think you’d even need to
explicitly pass the value of FILE there. (Would you?)

Not really, I just defined the default value just in case, but it’s true
that in this case it doesn’t make much sense.
El 02/06/2011 20:09, “Chad P.” [email protected] escribi:

Good Morning,

On Thu, Jun 2, 2011 at 6:30 AM, Ilias L. [email protected]
wrote:

The construct to detect execution of the file (in order to launch main
code) looks like this:

if FILE == $0
main
end

I would like a more elegant code.

I believe the following works but I always get myself into trouble in
these
areas so I may fall flat on my face here.

#test.rb
module Kernel
def executed?
caller[0].split(‘:’)[0] == $0
end
end

#test2.rb
require_relative ‘./test.rb’

if executed?
puts ‘Hello there’
else
puts ‘try again’
end

#test3.rb
require_relative ‘./test2’

ruby test2.rb
Hello there
ruby test3.rb
try again

#caller holds the stack including the file name of the caller so I
believe
you can use that instead of FILE in this case.

I tested this on ruby 1.9 but I believe it works in 1.8 as well.

John

011/6/2 Jess Gabriel y Galn [email protected]:

Not really, I just defined the default value just in case, but it’s true
that in this case it doesn’t make much sense.
El 02/06/2011 20:09, “Chad P.” [email protected] escribi:

Sorry for the top post and the bad quote, I was using my phone there.
What I wanted to say is that usually I try to think if there’s an
appropriate default value for a method parameter. And I just wrote
that, but obviously that default value is not very useful, and I can’t
come up with any other one. So I would write:

#executed.rb
module Kernel
def executed? file
file == $0
end
end

#main.rb
require ‘executed’
if executed? FILE
puts “Executed”
else
puts “Loaded”
end

Jesus.

On 2 Ιούν, 16:30, Ilias L. [email protected] wrote:

if executed?
print “works nice”
else
print "seems to fail
end
[…]

All 3 suggestion (Zotov, Galán, Higgins) failed on my site for
different reasons (e.g regex with “:” hits on P:/ on windows). Other
problems where with inclusions.

Using several constructs I saw, I came up with this one:

#mylib.rb
module Kernel
def executed?
re = /<(.*?)>/ # ? non-greedy, stops on first match
caller.to_s.match re # matches first text within <> in call-stack
#print caller.to_s
return $1 == “main” # first match was “main” means “executed”
end
end

if executed?
print “EXEC mylib\n”
end

#mytest.rb
require_relative ‘mylib’

if executed?
print “EXEC mytest\n”
end

#maintest.rb
require_relative ‘mylib’
require_relative ‘mytest’

if executed?
print “EXEC maintest\n”
end

ruby mylib.rb => EXEC mylib
ruby mylib.rb => EXEC mytest
ruby maintest.rb => EXEC maintest

I still dislike this solution, as it’s not clean.

Can it be expected to work stable (MRI 1.9.x is my main target)?

.

On Jun 3, 2011, at 9:05 AM, Ilias L. wrote:

end
end

ruby mylib.rb => EXEC mylib
ruby mylib.rb => EXEC mytest
ruby maintest.rb => EXEC maintest

I still dislike this solution, as it’s not clean.

What isn’t “clean” about it? You’ve reduced:

if FILE == $0

to:

if executed?

The whole point of adding that method to Kernel is so you don’t see the
work it is doing, right? In a perfect world, what would you like the
solution to look like?

cr

On 2 , 16:30, Ilias L. [email protected] wrote:

if executed?
print “works nice”
else
print "seems to fail
end

What would be the code for executed?

related issue:

Provide method Kernel#executed?

.

On 3 , 17:17, Chuck R. [email protected] wrote:

end
print “EXEC mytest\n”

ruby mylib.rb => EXEC mylib
ruby mylib.rb => EXEC mytest

correction:

ruby mytest.rb => EXEC mytest

ruby maintest.rb => EXEC maintest

I still dislike this solution, as it’s not clean.

What isn’t “clean” about it?
[…]

I am criticising myself.

My implementation is not “clean”, as it depends on the call stack /
regex.

.