5

動的に決定されるマウント ポイントがあり、ターゲット ボリュームで作業を行うための一連の絶対パスが提供されるプロジェクトに取り組んでいます。これらのファイルはまだ存在しないため、Pathname クラスを使用してファイル名の操作を処理しています。ただし、Pathname は、同じルートを持つパスを連結することに関しては、少し賢いことをしているようです。次の動作を観察しました。

p1 = Pathname.new('/foo/bar')                         # #<Pathname:/foo/bar>
p2 = Pathname.new('/baz/quux')                        # #<Pathname:/baz/quux>
p3 = p1 + p2                                          # #<Pathname:/baz/quux>
p4 = p1.join p2.relative_path_from(Pathname.new('/')) # #<Pathname:/foo/bar/baz/quux>
p5 = Pathname.new(p1.to_s.concat p2)                  # #<Pathname:/foo/bar/baz/quux>

したがって、p4 と p5 を使用すると、希望どおりの動作を得ることができますが、構造が少し不自然です。これを行うためのよりクリーンな方法はありますか?

4

2 に答える 2

5

ここでの Ruby の奇妙な動作は、文字列操作を使用して簡単に回避できます。

OPの例を借りて...

p1 = Pathname.new('/foo/bar')
p2 = '/baz/quux'
p1 + p2.sub(/\A\//, '')
# => #<Pathname:/foo/bar/baz/quux>

警告:操作を実行するには、2 番目p2が である必要があります。を使用してオブジェクトを簡単に変換できます。StringsubPathname#to_s

Pathname.new('/some/path/').to_s
# => "/some/path"
于 2014-09-24T19:41:06.960 に答える
4

細かいマニュアルから:

+(その他)

Pathname#+ は、これにパス名フラグメントを追加して、新しい Pathname オブジェクトを生成します。

p1 = Pathname.new("/usr")      # Pathname:/usr
p2 = p1 + "bin/ruby"           # Pathname:/usr/bin/ruby
p3 = p1 + "/etc/passwd"        # Pathname:/etc/passwd

鉱山を強調します。Pathnameの+演算子は、パス名のフラグメントを追加するように指定されています、先頭にスラッシュがあるパス名はフラグメントではありません。ドキュメントでは、2 つのパス名を追加したり、パス名に非フラグメントを追加したりした場合にどうなるかは明示的に指定されていませんが、例は期待される動作が見られることを示しています。

于 2012-09-17T17:47:14.490 に答える