Project

General

Profile

Actions

Bug #2731

closed

FileUtils.copy prints error message in $DEBUG mode when destination doesn't exist

Added by murphy (Kornelius Kalnbach) over 14 years ago. Updated over 13 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.2dev (2010-02-04 trunk 26573) [i386-darwin10.2.0]
Backport:
[ruby-core:28141]

Description

=begin
Trying to copy a file with Ruby:

$ touch source
$ ls destination
ls: destination: No such file or directory
$ ruby -rfileutils -d -e 'FileUtils.copy "source", "destination"'
Exception `Errno::ENOENT' at /usr/local/lib/ruby/1.9.1/fileutils.rb:1429 - No such file or directory - destination
$ ls destination
destination

While the copy succeeds, it prints this confusing message. I don't expect libraries to issue exceptions when performing standard operations. This affects the FileUtils methods install, mv, cp_r, and cp; but the problem is in Entry_#fu_same? (around lib/fileutils.rb:1426):

def fu_same?(a, b) #:nodoc:
if fu_have_st_ino?
st1 = File.stat(a)
st2 = File.stat(b)
st1.dev == st2.dev and st1.ino == st2.ino
else
File.expand_path(a) == File.expand_path(b)
end
rescue Errno::ENOENT
return false
end

So, File.stat(b) is checked even if b doesn't exist. The resulting error message is even explicitely captured and hidden by the rescue. For the methods in question, it is a common case that the destination file doesn't exist.

Here's a version that doesn't rely on exceptions:

def fu_same?(a, b) #:nodoc:
return false if !File.exist?(a) || !File.exist?(b)
if fu_have_st_ino?
st1 = File.stat(a)
st2 = File.stat(b)
st1.dev == st2.dev and st1.ino == st2.ino
else
File.expand_path(a) == File.expand_path(b)
end
end

The problem exists across Ruby versions from 1.8.6 to 1.9.2dev.
=end

Actions #1

Updated by mame (Yusuke Endoh) over 14 years ago

  • Status changed from Open to Rejected

=begin
Hi,

2010/2/10 Kornelius Kalnbach :

Trying to copy a file with Ruby:

$ touch source
$ ls destination
ls: destination: No such file or directory
$ ruby -rfileutils -d -e 'FileUtils.copy "source", "destination"'
Exception `Errno::ENOENT' at /usr/local/lib/ruby/1.9.1/fileutils.rb:1429 - No such file or directory - destination
$ ls destination
destination

While the copy succeeds, it prints this confusing message.

You say, library must not use an exception for internal implementation?
The convension is uneasy and too uncomfortable for library authors.

In old convension, an exception might be for exceptional condition.
But currently, it has many use cases not only to represent exceptional
condition but also to represent normal condition (e.g., StopIteration),
to control execution (e.g., DSL), etc.

So this is not a bug and I close the ticket.
Rather, we should reconsider the purpose and behavior of $DEBUG.
Currently, it is worthless in effect.

--
Yusuke ENDOH
=end

Actions #2

Updated by murphy (Kornelius Kalnbach) over 14 years ago

=begin
On 11.04.10 16:08, Yusuke Endoh wrote:

You say, library must not use an exception for internal implementation?
The convension is uneasy and too uncomfortable for library authors.

In old convension, an exception might be for exceptional condition.
But currently, it has many use cases not only to represent exceptional
condition but also to represent normal condition (e.g., StopIteration),
to control execution (e.g., DSL), etc.
You're right. I agree that it's not a bug, more like an inconvenient
behavior. The patch might still be an improvement.

The only workaround I know is:

debug, $DEBUG = $DEBUG, false
FileUtils.copy source, destination
$DEBUG = debug

I don't like such constructs because they look ugly (aka "noise").

So this is not a bug and I close the ticket.
Rather, we should reconsider the purpose and behavior of $DEBUG.
Currently, it is worthless in effect.
Spontaneous idea: Setting $DEBUG to an Exception class or an array of
such classes to specify which exception you want to debug. Improving
Rubys debugging capabilities can't hurt.

[murphy]

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0