Lỗi 'yêu cầu' của Ruby: không thể tải tập tin đó


169

Tôi có một tệp, main.rb với nội dung sau:

require "tokenizer.rb"

Tệp tokenizer.rb nằm trong cùng thư mục và nội dung của nó là:

class Tokenizer
    def self.tokenize(string)
        return string.split(" ")
    end
end

Nếu tôi cố chạy main.rb, tôi gặp lỗi sau:

C:\Documents and Settings\my\src\folder>ruby main.rb

C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- tokenizer.rb (LoadError)
        from C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require '
        from main.rb:1:in `<main>'

Tôi chỉ nhận thấy rằng nếu tôi sử dụng loadthay vì requiremọi thứ hoạt động tốt. Vấn đề có thể ở đây là gì?



Kiểm tra xem tệp có .rbphần mở rộng
onmyway133

Câu trả lời:


189

Tôi chỉ cần thử và nó hoạt động với require "./tokenizer". Hi vọng điêu nay co ich.


15
Điều này giả định rằng CWD là thư mục mà các tập lệnh được lưu trữ.
David Grayson

25
... đó là lý do tại sao tôi nghĩ tốt hơn là sử dụng require_relativenhư tôi đã làm trong câu trả lời của mình.
David Grayson

180

Chỉ cần làm điều này:

require_relative 'tokenizer'

Nếu bạn đặt tệp này trong tệp Ruby nằm trong cùng thư mục tokenizer.rb, nó sẽ hoạt động tốt cho dù thư mục làm việc hiện tại của bạn (CWD) là gì.

Giải thích tại sao đây là cách tốt nhất

Các câu trả lời khác cho rằng bạn nên sử dụng require './tokenizer', nhưng đó là câu trả lời sai , vì nó sẽ chỉ hoạt động nếu bạn chạy quy trình Ruby của mình trong cùng thư mục tokenizer.rb. Rất nhiều lý do duy nhất để xem xét sử dụng requirenhư vậy là nếu bạn cần hỗ trợ Ruby 1.8 mà không có require_relative.

Câu require './tokenizer'trả lời có thể phù hợp với bạn ngày hôm nay, nhưng nó không cần thiết giới hạn các cách mà bạn có thể chạy mã Ruby của mình. Ngày mai, nếu bạn muốn di chuyển các tệp của mình sang một thư mục khác hoặc chỉ muốn bắt đầu quá trình Ruby của mình từ một thư mục khác, bạn sẽ phải suy nghĩ lại về tất cả các requiretuyên bố đó.

Sử dụng requiređể truy cập các tệp trên đường dẫn tải là một điều tốt và đá quý Ruby làm điều đó mọi lúc. Nhưng bạn không nên bắt đầu cuộc tranh cãi requirevới một .trừ khi bạn đang làm điều gì đó rất đặc biệt và biết bạn đang làm gì.

Khi bạn viết mã đưa ra các giả định về môi trường của nó, bạn nên suy nghĩ cẩn thận về những giả định cần thực hiện. Trong trường hợp này, có tối đa ba cách khác nhau để yêu cầu tokenizertệp và mỗi cách đưa ra một giả định khác nhau:

  1. require_relative 'path/to/tokenizer': Giả sử rằng đường dẫn tương đối giữa hai tệp nguồn Ruby sẽ giữ nguyên.
  2. require 'path/to/tokenizer': Giả sử path/to/tokenizerbên trong một trong các thư mục trên đường dẫn tải ( $LOAD_PATH). Điều này thường yêu cầu thiết lập thêm, vì bạn phải thêm một cái gì đó vào đường dẫn tải.
  3. require './path/to/tokenizer': Giả sử rằng đường dẫn tương đối từ thư mục làm việc hiện tại của quy trình Ruby tokenizer.rbsẽ không thay đổi.

Tôi nghĩ rằng đối với hầu hết mọi người và hầu hết các tình huống, các giả định được đưa ra trong các lựa chọn # 1 và # 2 có nhiều khả năng giữ đúng theo thời gian.


Bạn có thể vui lòng cho biết ý nghĩa của việc này? Nó làm gì đằng sau hậu trường? Cảm ơn.
sid smith

Không có nhiều điều để biết. Đây là tài liệumã nguồn cho allow_relative.
David Grayson

90

Ruby 1.9 đã xóa thư mục hiện tại khỏi đường dẫn tải và do đó bạn sẽ cần thực hiện một yêu cầu tương đối trên tệp này, như David Grayson nói:

require_relative 'tokenizer'

Không cần phải có hậu tố .rb, vì Ruby đủ thông minh để biết đó là điều bạn muốn nói.


1
Tôi biết điều này sẽ là một điều ngu ngốc, cảm ơn vì sự giúp đỡ
The Coding Monk

3
Điều này giả định rằng CWD là thư mục mà các tập lệnh được lưu trữ.
David Grayson

@RyanBigg - Tôi mới chơi ruby. Bạn có thể vui lòng giải thích điều này có nghĩa là Ruby 1.9 has removed the current directory from the load pathgì - ? Thư mục hiện tại và đường dẫn tải là gì? Cảm ơn.
sid smith

Tôi nên đọc gì trong OP? Chỉ vì OP tình cờ có CWD bằng với thư mục với các tập lệnh không có nghĩa là nó sẽ luôn như vậy, vì vậy tôi muốn thúc đẩy một giải pháp mạnh mẽ hơn như sử dụng require_relative. Ngày mai anh ấy có thể gõ cd ..và sau đó ruby folder/main.rbvà buồn là giải pháp của bạn không còn hiệu quả nữa. Tôi không nghĩ rằng việc sử dụng requirecó bất kỳ lợi ích nào ở đây.
David Grayson

1
Đã cập nhật cho require_relative(không tồn tại hoặc tôi không biết về nó tại thời điểm đăng)
Ryan Bigg

37

requiretải một tập tin từ $LOAD_PATH. Nếu bạn muốn yêu cầu một tệp liên quan đến tệp hiện đang thực thi thay vì từ $LOAD_PATH, hãy sử dụng require_relative.


14

Tôi muốn giới thiệu,

load './tokenizer.rb'

Cho rằng bạn biết các tập tin trong cùng một thư mục làm việc.

Nếu bạn đang cố yêu cầu nó liên quan đến tệp, bạn có thể sử dụng

require_relative 'tokenizer'

Tôi hi vọng cái này giúp được.


11

Một phương pháp nhỏ khác là đưa thư mục hiện tại vào đường dẫn tải của bạn với

$:.unshift('.')

Bạn có thể đẩy nó lên mảng $: ($ LOAD_PATH) nhưng việc không dịch chuyển sẽ buộc nó tải thư mục làm việc hiện tại của bạn trước phần còn lại của đường dẫn tải.

Khi bạn đã thêm thư mục hiện tại của mình vào đường dẫn tải, bạn không cần tiếp tục chỉ định

 require './tokenizer' 

và có thể quay lại sử dụng

require 'tokenizer'

5

Điều này sẽ hoạt động tốt nếu nó nằm trong thư mục gem lib và đây là tokenizer.rb

require_relative 'tokenizer/main'

1

Tôi đã sử dụng jruby-1.7.4 để biên dịch mã ruby ​​của mình.

require 'roman-numerals.rb' 

là mã đã ném lỗi dưới đây.

LoadError: no such file to load -- roman-numerals
  require at org/jruby/RubyKernel.java:1054
  require at /Users/amanoharan/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
   (root) at /Users/amanoharan/Documents/Aptana Studio 3 Workspace/RubyApplication/RubyApplication1/Ruby2.rb:2

Tôi đã loại bỏ rb khỏi yêu cầu và đưa ra

require 'roman-numerals' 

Nó hoạt động tốt.


1

Đối với những người hoàn toàn chắc chắn đường dẫn tương đối của họ là chính xác, vấn đề của tôi là các tệp của tôi không có .rbphần mở rộng! (Mặc dù tôi đã từng RubyMinetạo các tệp và chọn rằng chúng là Rubycác tệp khi tạo.)

Kiểm tra kỹ các phần mở rộng tập tin trên tập tin của bạn!


1

Điều gì về bao gồm các thư mục hiện tại trong đường dẫn tìm kiếm?

ruby -I. main.rb

0

Vấn đề là requirekhông tải từ thư mục hiện tại. Đây là những gì tôi nghĩ, nhưng sau đó tôi tìm thấy chủ đề này . Ví dụ tôi đã thử đoạn mã sau:

irb> f = File.new('blabla.rb')
=> #<File:blabla.rb>
irb> f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
LoadError: cannot load such file -- blabla.rb
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
        from (irb):24
        from D:/dev/Ruby193/bin/irb:12:in `<main>'

Như có thể thấy nó đọc tập tin ok, nhưng tôi không thể yêu cầu nó (đường dẫn không được nhận ra). và ở đây có mã hoạt động:

irb f = File.new('D://blabla.rb')
=> #<File:D://blabla.rb>
irb f.read
=> "class Tokenizer\n    def self.tokenize(string)\n        return string.split(
\" \")\n    end\nend\n"
irb> require f
=> true

Như bạn có thể thấy nếu bạn chỉ định đường dẫn đầy đủ, tệp sẽ tải chính xác.


1
Đó là một vấn đề của sự lựa chọn. Cá nhân tôi luôn muốn kiểm tra những gì tôi đang làm trong bảng điều khiển tương tác. Tôi mắc khá nhiều lỗi và tôi thích nhận phản hồi tương tác.
Boris Strandjev 17/03/2016

0

Đầu tiên :

$ sudo gem install colored2

Và, bạn nên nhập mật khẩu của bạn

Sau đó :

$ sudo gem update --system  

Xuất hiện Cập nhật rubygems-update ERROR: Trong khi thực thi gem ... (OpenSSL :: SSL :: SSLError) tên máy chủ "Gem.ruby-china.org" không khớp với chứng chỉ máy chủ

Sau đó:

$  rvm -v
$ rvm get head

Cuối cùng bạn muốn sử dụng ngôn ngữ nào ?? [Swift / ObjC]

ObjC

Bạn có muốn bao gồm một ứng dụng demo với thư viện của bạn? [ Có không ]

Đúng

Những khung kiểm tra nào bạn sẽ sử dụng? [Specta / Kiwi / Không]

không ai

Bạn có muốn làm thử nghiệm dựa trên xem? [ Có không ]

Không

Tiền tố lớp học của bạn là gì?

XMG

Chạy pod cài đặt trên thư viện mới của bạn.


-2

bạn cần đưa ra con đường. Atleast bạn nên đưa ra đường dẫn từ thư mục hiện tại. Nó sẽ làm việc chắc chắn. ./filename


Để rõ ràng, tôi nghĩ bạn nên đưa ra một phần mã lặp lại ở đây với bản sửa lỗi. Bỏ phiếu không phải là của tôi
Rohit Gupta
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.