SUSv3ã®realpath(3)ã®é …ã«ã¯ã€å˜åœ¨ã—ãªã„コンãƒãƒ¼ãƒãƒ³ãƒˆãŒã‚ã£ãŸã‚‰
errno=ENOENT ã‚’è¿”ã™ã¹ã—(shall fail)ã¨ã‚ã‚‹ã®ã§ã™ãŒã€*BSDã§ã¯æœ€å¾Œã®
コンãƒãƒ¼ãƒãƒ³ãƒˆã«é™ã‚Šå˜åœ¨ã—ãªãã¦ã‚‚ã„ã„(All but the last component
must exist)実装ã«ãªã£ã¦ã„ã¦ã€å®Ÿç”¨ä¸Šãã®æ–¹ãŒä¾¿åˆ©ãªå ´åˆãŒå°‘ãªã‹ã‚‰ãš
ã‚りã¾ã™ã€‚
 Pathname#realpath()ã¯SUSv3ã®ä»•様をè¸è¥²ã—ãŸå®Ÿè£…ã«ãªã£ã¦ã„ã¾ã™ãŒã€
Pathname自体ã¯ç”Ÿæˆæ™‚点ã§å˜åœ¨ã—ãªã„パスも許ã—ã¾ã™ã—ã€ã“れã‹ã‚‰ç”Ÿæˆ
ã—よã†ã¨ã™ã‚‹ãƒ•ァイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ‘スåã‚’æ£è¦åŒ–ã™ã‚‹ã‚ˆã†ãª
æ“作ãŒã§ãã‚‹ã¨ä¾¿åˆ©ã§ã™ã€‚
 ã¨ã„ã£ã¦Pathname#realpath()ã®ä»•様を変ãˆã‚‹ã®ã¯å¥½ã¾ã—ããªã„ã®ã§ã€
#abspath()ã¨ã„ã†åˆ¥ãƒ¡ã‚½ãƒƒãƒ‰ã®è¿½åŠ ã‚’ææ¡ˆã—ã¾ã™ã€‚ã©ã†ã§ã—ょã†ã‹ã€‚
Index: ChangeLog
— ChangeLog (revision 19332)
+++ ChangeLog (working copy)
@@ -1,3 +1,9 @@
+Sun Sep 14 05:51:02 2008 Akinori MUSHA [email protected]
+
-
- lib/pathname.rb (Pathname#realpath_rec, Pathname#abspath): Add
- Pathname#abspath, a variant of #realpath that allows the last
- component of pathname to be nonexistent.
Sun Sep 14 03:20:03 2008 Tanaka A. [email protected]
- include/ruby/oniguruma.h (onigenc_get_prev_char_head): add end
Index: lib/pathname.rb
===================================================================
— lib/pathname.rb (revision 19332)
+++ lib/pathname.rb (working copy)
@@ -76,9 +76,9 @@
=== Core methods
-# These methods are effectively manipulating a String, because that’s
all a path
-# is. Except for #mountpoint?, #children, and #realpath, they don’t
access the
-# filesystem.
+# These methods are effectively manipulating a String, because that’s
+# all a path is. Except for #mountpoint?, #children, #abspath and
+# #realpath, they don’t access the filesystem.
- +
- #join
@@ -89,6 +89,7 @@
- #relative_path_from
- #each_filename
- #cleanpath
+# - #abspath
- #realpath
- #children
- #mountpoint?
@@ -411,7 +412,7 @@ class Pathname
end
private :cleanpath_conservative
- def realpath_rec(prefix, unresolved, h)
- def realpath_rec(prefix, unresolved, h, strict, last = true)
resolved = []
until unresolved.empty?
n = unresolved.shift
@@ -428,14 +429,20 @@ class Pathname
prefix, *resolved = h[path]
end
else
-
s = File.lstat(path)
-
begin
-
s = File.lstat(path)
-
rescue Errno::ENOENT => e
-
raise e if strict || !last || !unresolved.empty?
-
resolved << n
-
break
-
end if s.symlink? h[path] = :resolving link_prefix, link_names = split_names(File.readlink(path)) if link_prefix == ''
-
prefix, *resolved = h[path] = realpath_rec(prefix,
resolved + link_names, h)
-
prefix, *resolved = h[path] = realpath_rec(prefix,
resolved + link_names, h, strict, unresolved.empty?)
else
-
prefix, *resolved = h[path] = realpath_rec(link_prefix,
link_names, h)
-
prefix, *resolved = h[path] = realpath_rec(link_prefix,
link_names, h, strict, unresolved.empty?)
end
else
resolved << n
@@ -449,19 +456,33 @@ class Pathname
private :realpath_rec
filesystem.
-
Returns the real (absolute) pathname of +self+ in the actual
-
filesystem not containing symlinks or useless dots.
-
-
All components of the pathname must exist when this method is
-
called.
No arguments should be given; the old behaviour is obsoleted.
def realpath
- abspath(true)
- end
-
-
Returns the real (absolute) pathname of +self+ in the actual
filesystem.
-
The real pathname doesn’t contain symlinks or useless dots.
-
-
The last component of the pathname can be nonexistent unless
-
+strict+ is set to true.
-
- def abspath(strict = false)
path = @path
prefix, names = split_names(path)
if prefix == ‘’
prefix, names2 = split_names(Dir.pwd)
names = names2 + names
end
- prefix, *names = realpath_rec(prefix, names, {})
- prefix, *names = realpath_rec(prefix, names, {}, strict)
self.class.new(prepend_prefix(prefix, File.join(*names)))
end
Index: test/pathname/test_pathname.rb
— test/pathname/test_pathname.rb (revision 19332)
+++ test/pathname/test_pathname.rb (working copy)
@@ -281,13 +281,45 @@ class TestPathname < Test::Unit::TestCas
rescue TypeError
end
Dir.mktmpdir(‘rubytest-pathname’) {|dir|
-
assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") } File.symlink("not-exist-target", "#{dir}/not-exist") assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") }
-
File.symlink("../#{File.basename(dir)}/./not-exist-target",
“#{dir}/not-exist2”)
-
assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist2") }
-
File.open("#{dir}/exist-target", "w") {}
-
File.symlink("../#{File.basename(dir)}/./exist-target",
“#{dir}/exist”)
-
assert_nothing_raised { realpath("#{dir}/exist") } File.symlink("loop", "#{dir}/loop") assert_raise(Errno::ELOOP) { realpath("#{dir}/loop") }
}
end -
def abspath(path)
-
Pathname.new(path).abspath.to_s
-
end
-
def test_abspath
-
begin
-
File.symlink(nil, nil)
-
rescue NotImplementedError
-
return
-
rescue TypeError
-
end
-
Dir.mktmpdir(‘rubytest-pathname’) {|dir|
-
assert_nothing_raised { abspath("#{dir}/not-exist") }
-
assert_raise(Errno::ENOENT) {
realpath(“#{dir}/not-exist/not-exist-child”) }
-
File.symlink("not-exist-target", "#{dir}/not-exist")
-
assert_nothing_raised { abspath("#{dir}/not-exist") }
-
File.symlink("../#{File.basename(dir)}/./not-exist-target",
“#{dir}/not-exist2”)
-
assert_nothing_raised { abspath("#{dir}/not-exist2") }
-
File.open("#{dir}/exist-target", "w") {}
-
File.symlink("../#{File.basename(dir)}/./exist-target",
“#{dir}/exist”)
-
assert_nothing_raised { abspath("#{dir}/exist") }
-
File.symlink("loop", "#{dir}/loop")
-
assert_raise(Errno::ELOOP) { abspath("#{dir}/loop") }
- }
- end
- def descend(path)
Pathname.new(path).enum_for(:descend).map {|v| v.to_s }
end