Accessing a file in ruby - differences
Question
What is the different between the following statements?
#(not working)
File.exists?("path to file")
#(working)
::File.exists?("path to file")
I used above statements in Chef framework of Ruby.
Solution
Here is possible try to replicate your issue :
Not working :
class Foo< BasicObject
def self.file_size
File.size(__FILE__)
end
end
p Foo.file_size # uninitialized constant Foo::File (NameError)
The reason is File
class is available to the top level ( i.e. in the scope of the class Object
) and inside any class which is a direct/ indirect subclass of Object
. But Foo
has no relation with Object
, you wouldn't be able to access it inside Foo
, if you don't tell it, from where File
class ( or constant ) actually accessible.
Working :
class Foo< BasicObject
def self.file_size
::File.size(__FILE__)
end
end
p Foo.file_size # => 132
Although here also, Foo
has no relation with Object
, but we are explicitly ( by using ::
constant scope resolution operator ) telling Ruby that from where we are trying to access the File
class ( Remember class(s) are also constant in Ruby) inside Foo
class. Thus here is no objection from Ruby.
Check out if such situation is present in your code too.
OTHER TIPS
There is another constant named File
in the scope where you are using File.exists?("path to file")
. But when you use the ::
operator, you are telling ruby to find the File
constant in Object
(Object::File
)
On a side-note, File.exists? is deprecated - use File.exist?
According to maty, the question should be asked in this way:
"object, do you exist?" "object.exist?"
Keep this in mind - yes, "if file exist" is not proper english, but asking it that way would be wrong from the ruby object point of view.
As for the leading :: - this refers to toplevel scope.
It is not often required, usually only when you have the same name of a class or a module.