Cách mở tệp liên quan đến thư mục chính


94

Điều sau không thành công với Errno::ENOENT: No such file or directory, ngay cả khi tệp tồn tại:

open('~/some_file')

Tuy nhiên, tôi có thể làm điều này:

open(File.expand_path('~/some_file'))

Tôi có hai câu hỏi:

  1. Tại sao không openxử lý dấu ngã khi trỏ đến thư mục chính?
  2. Có cách nào trơn tru hơn File.expand_pathkhông?

Câu trả lời:


109
  1. Shell (bash, zsh, v.v.) chịu trách nhiệm mở rộng ký tự đại diện, vì vậy trong ví dụ đầu tiên của bạn không có shell, do đó không có mở rộng. Sử dụng dấu ngã để trỏ đến chỉ $HOMElà một quy ước; thực sự, nếu bạn nhìn vào tài liệu File.expand_path, nó diễn giải chính xác dấu ngã, nhưng đó là một đặc điểm của chính hàm, không phải thứ vốn có đối với hệ thống cơ bản; đồng thời, File.expand_pathyêu cầu $HOMEbiến môi trường phải được đặt chính xác. Điều này đưa chúng ta đến giải pháp thay thế khả thi ...
  2. Thử cái này:

    open(ENV['HOME']+'/some_file')

Tôi hy vọng nó đủ bóng bẩy. Cá nhân tôi nghĩ rằng sử dụng một biến môi trường rõ ràng hơn về mặt ngữ nghĩa so với việc sử dụng expand_path.


sử dụng các cửa sổ .. phải làmopen(ENV['HOME']+'some_file')
David Tây

9
Sử dụng đơn giản File.join(ENV['HOME'], '/some_file')để nó hoạt động trong cả hai trường hợp.
Marcin Bilski

122

Không chắc liệu điều này đã có trước Ruby 1.9.3 hay chưa nhưng tôi thấy rằng giải pháp thanh lịch nhất là sử dụng Dir.homenó là một phần của cốt lõi.

open("#{Dir.home}/some_file")

2
Không, không khả dụng cho người dùng dưới 1.9.3 ( apidock.com/ruby/v1_9_2_180/Dir/home/class ).
Ian Vaughan

12

Thay vì dựa vào $HOMEbiến môi trường được đặt chính xác, điều này có thể gây rắc rối khi bạn sử dụng các máy tính mạng dùng chung để phát triển, bạn có thể lấy điều này từ Ruby bằng cách sử dụng:

require 'etc'
open ("#{Etc.getpwuid.dir}/some_file")

Tôi tin rằng điều này xác định người dùng đã đăng nhập hiện tại và lấy thư mục chính của họ thay vì dựa vào $HOMEbiến môi trường toàn cầu đang được đặt. Đây là một giải pháp thay thế cho những điều tôi nghĩ ở trên.


2

Tôi đã phát hiện ra vấn đề về dấu ngã và một bản vá đã được tạo ra để thêm absolute_path những dấu ngã coi như một ký tự bình thường.

Từ tài liệu Tệp:

absolute_path(file_name [, dir_string] )  abs_file_name

Chuyển đổi tên đường dẫn thành tên đường dẫn tuyệt đối. Các đường dẫn tương đối được tham chiếu từ thư mục làm việc hiện tại của quá trình trừ khi dir_string được đưa ra, trong trường hợp đó nó sẽ được sử dụng làm điểm bắt đầu. Nếu tên đường dẫn đã cho bắt đầu bằng “~” thì nó KHÔNG được mở rộng, nó được coi là tên thư mục bình thường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.