File.delete one-liner


#1

Hi guys,

I’m looking for a single line that essentially deletes the lockfile
argument passed to the unlock method, or deletes the instance variable
(default) lockfile. Like this, but simpler:

@lockfile = some_other_lockfile

def self.unlock(lockfile)
if File.exist?(lockfile)
File.delete(lockfile)
else
File.delete(@lockfile)
end
end

I was thinking of something along the following:

@lockfile = some_other_lockfile

def self.unlock
File.delete(lockfile) || File.delete(@lockfile)
end

…however, the File.delete method doesn’t return a true/false value
based on its success.

Any tips? Thanks in advance!

-David


#2

David S. wrote:

File.delete(lockfile)

def self.unlock
File.delete(lockfile) || File.delete(@lockfile)
end

…however, the File.delete method doesn’t return a true/false value
based on its success.

Any tips? Thanks in advance!

-David

Use exceptions?

begin
File.delete(lf)
rescue Errno::ENOENT
File.delete(@lf)
end


#3

Use exceptions?

begin
File.delete(lf)
rescue Errno::ENOENT
File.delete(@lf)
end

Thanks Joel. Forgive me, I’m just learning Ruby/scripting/programming. I
believe I understand your example, but (as far as I can tell) it doesn’t
really accomplish my goal, and seems to have the same functionality of
my first (longer) example.

Please let me know if I’ve missed something. :slight_smile:

In any case, I think I found a (seemingly) obvious solution to my
question:

@lockfile = some_other_lockfile

def self.unlock(lockfile)
File.exist?(lockfile) ? File.delete(lockfile) : File.delete(@lockfile)
end

Thanks again!

-David


#4

File.delete(File.exists?(lockfile) ? lockfile : @lockfile)

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

On 04/02/2009, at 5:07 AM, Joel VanderWerf removed_email_address@domain.invalid


#5

2009/2/4 Julian L. removed_email_address@domain.invalid:

File.delete(File.exists?(lockfile) ? lockfile : @lockfile)

[lockfile, @lockfile].any? {|f| File.delete(f) rescue false}

Cheers

robert


#6

David S. wrote:

really accomplish my goal, and seems to have the same functionality of
File.exist?(lockfile) ? File.delete(lockfile) : File.delete(@lockfile)
end

With exceptions, you are saying “try to delete lf; if that fails
(because the file doesn’t exist) then try to delete @lf”. Other failures
(e.g., lf permissions are wrong, or @lf doesn’t exist) are reported
normally as exceptions.

One advantage to doing it this way is that the delete is an atomic
operation. With

File.exist?(lockfile) ? File.delete(lockfile) : 

File.delete(@lockfile)

there is the possiblity that #exist? will return true, but in the brief
time before #delete is called, some other process deletes the file.

Btw, it looks to me like your #unlock implementation above is the same
as your first implementation. The ? : construct is really the same as
if…else, just more compact.


#7

Robert K. wrote:

2009/2/4 Julian L. removed_email_address@domain.invalid:

File.delete(File.exists?(lockfile) ? lockfile : @lockfile)

[lockfile, @lockfile].any? {|f| File.delete(f) rescue false}

If #delete fails on lockfile for some reason other than ENOENT, this
code will try to delete @lockfile.


#8

On 05.02.2009 18:49, Joel VanderWerf wrote:

Robert K. wrote:

2009/2/4 Julian L. removed_email_address@domain.invalid:

File.delete(File.exists?(lockfile) ? lockfile : @lockfile)
[lockfile, @lockfile].any? {|f| File.delete(f) rescue false}

If #delete fails on lockfile for some reason other than ENOENT, this
code will try to delete @lockfile.

This is correct. I thought that was intended. Didn’t you suggest
exactly this in your previous posting (atomic deletion)? Looking at the
original question it is not clear in which cases @lockfile should be
deleted - unless you take the code as spec.

Thanks for pointing this out!

Cheers

robert


#9

Robert K. wrote:

exactly this in your previous posting (atomic deletion)? Looking at the
original question it is not clear in which cases @lockfile should be
deleted - unless you take the code as spec.

Thanks for pointing this out!

The only difference in my suggestion was to “Rescue Errno::ENOENT”,
which seems closer to the original intent of using #exists?..

begin
File.delete(lf)
rescue Errno::ENOENT
File.delete(@lf)
end