Galat 'wajib' Ruby: tidak dapat memuat file seperti itu

169

Saya punya satu file, main.rb dengan konten berikut:

require "tokenizer.rb"

File tokenizer.rb berada di direktori yang sama dan kontennya adalah:

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

Jika saya mencoba menjalankan main.rb saya mendapatkan kesalahan berikut:

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>'

Saya hanya memperhatikan bahwa jika saya gunakan, loadbukannya requiresemuanya bekerja dengan baik. Apa masalahnya di sini?

Biarawan Pengkodean
sumber
Pertanyaan terkait: stackoverflow.com/questions/2900370/…
Andrew Grimm
Pastikan file tersebut memiliki .rbekstensi
onmyway133

Jawaban:

189

Saya baru saja mencoba dan berfungsi dengan baik require "./tokenizer". Semoga ini membantu.

Pascal
sumber
15
Ini mengasumsikan bahwa CWD adalah direktori tempat skrip disimpan.
David Grayson
25
... itu sebabnya saya pikir lebih baik menggunakan require_relativeseperti yang saya lakukan dalam jawaban saya.
David Grayson
180

Lakukan saja ini:

require_relative 'tokenizer'

Jika Anda meletakkan ini dalam file Ruby yang ada di direktori yang sama tokenizer.rb, itu akan berfungsi dengan baik apa pun direktori kerja Anda saat ini (CWD).

Penjelasan mengapa ini adalah cara terbaik

Jawaban lain mengklaim bahwa Anda harus menggunakan require './tokenizer', tetapi itu adalah jawaban yang salah , karena itu hanya akan berfungsi jika Anda menjalankan proses Ruby Anda di direktori yang sama dengan yang tokenizer.rbada. Cukup satu-satunya alasan untuk mempertimbangkan menggunakan requireseperti itu adalah jika Anda perlu mendukung Ruby 1.8, yang tidak ada require_relative.

The require './tokenizer'jawaban mungkin bekerja untuk Anda hari ini, tetapi tidak perlu membatasi cara di mana Anda dapat menjalankan kode Ruby Anda. Besok, jika Anda ingin memindahkan file ke direktori lain, atau hanya ingin memulai proses Ruby Anda dari direktori lain, Anda harus memikirkan kembali semua requirepernyataan itu.

Menggunakan requireuntuk mengakses file yang berada di jalur pemuatan adalah hal yang baik dan permata Ruby selalu melakukannya. Tetapi Anda tidak harus memulai argumen requiredengan .kecuali Anda melakukan sesuatu yang sangat istimewa dan tahu apa yang Anda lakukan.

Ketika Anda menulis kode yang membuat asumsi tentang lingkungannya, Anda harus berpikir dengan hati-hati tentang asumsi yang akan dibuat. Dalam hal ini, ada hingga tiga cara berbeda untuk memerlukan tokenizerfile, dan masing-masing membuat asumsi yang berbeda:

  1. require_relative 'path/to/tokenizer': Diasumsikan bahwa jalur relatif antara dua file sumber Ruby akan tetap sama.
  2. require 'path/to/tokenizer': Menganggap bahwa path/to/tokenizerada di dalam salah satu direktori di jalur pemuatan ( $LOAD_PATH). Ini biasanya memerlukan pengaturan tambahan, karena Anda harus menambahkan sesuatu ke jalur pemuatan.
  3. require './path/to/tokenizer': Menganggap bahwa jalur relatif dari direktori kerja proses Ruby saat ini ke tokenizer.rbakan tetap sama.

Saya pikir bahwa bagi kebanyakan orang dan sebagian besar situasi, asumsi yang dibuat dalam opsi # 1 dan # 2 lebih mungkin berlaku seiring berjalannya waktu.

David Grayson
sumber
Bisakah Anda memberi tahu apa artinya ini? Apa yang dilakukan di balik layar? Terima kasih.
sid smith
Tidak banyak yang tahu. Berikut dokumentasi dan kode sumber untuk require_relative.
David Grayson
90

Ruby 1.9 telah menghapus direktori saat ini dari jalur pemuatan, jadi Anda harus melakukan persyaratan relatif pada file ini, seperti yang dikatakan David Grayson:

require_relative 'tokenizer'

Tidak perlu untuk membuatnya sufiks .rb, karena Ruby cukup pintar untuk mengetahui apa yang Anda maksudkan.

Ryan Bigg
sumber
1
Saya tahu ini akan menjadi hal yang bodoh, terima kasih atas bantuannya
The Coding Monk
3
Ini mengasumsikan bahwa CWD adalah direktori tempat skrip disimpan.
David Grayson
@RyanBigg - Saya baru mengenal ruby. Bisakah Anda jelaskan apa artinya ini - Ruby 1.9 has removed the current directory from the load path? Apa direktori saat ini dan jalur muat? Terima kasih.
sid smith
Apa yang harus saya baca di OP? Hanya karena OP kebetulan memiliki CWD yang sama dengan direktori dengan skrip tidak berarti selalu akan seperti itu, jadi saya ingin mendorong solusi yang lebih kuat seperti menggunakan require_relative. Besok dia mungkin mengetik cd ..dan kemudian ruby folder/main.rbdan sedih solusi Anda tidak bekerja lagi. Saya tidak berpikir bahwa menggunakan requirememiliki manfaat apa pun di sini.
David Grayson
1
Diperbarui untuk require_relative(yang tidak ada, atau saya tidak tahu tentang itu, pada saat posting)
Ryan Bigg
37

requirememuat file dari $LOAD_PATH. Jika Anda ingin memerlukan file relatif terhadap file yang sedang dijalankan bukan dari $LOAD_PATH, gunakan require_relative.

Jörg W Mittag
sumber
14

Saya ingin merekomendasikan,

load './tokenizer.rb'

Mengingat, Anda tahu file itu di direktori kerja yang sama.

Jika Anda mencoba untuk membuatnya relatif terhadap file, Anda dapat menggunakannya

require_relative 'tokenizer'

Saya harap ini membantu.

Matthew Brock Carey
sumber
11

Metode kecil yang bagus adalah dengan menyertakan direktori saat ini di jalur beban Anda

$:.unshift('.')

Anda bisa mendorongnya ke array $: ($ LOAD_PATH) tetapi unshift akan memaksanya untuk memuat direktori Anda saat ini sebelum sisa jalur muat.

Setelah Anda menambahkan direktori Anda saat ini di jalur muat Anda, Anda tidak perlu terus menentukan

 require './tokenizer' 

dan bisa kembali menggunakan

require 'tokenizer'
Pseudomonkey
sumber
5

Ini akan bekerja dengan baik jika berada di direktori lib permata dan ini adalah tokenizer.rb

require_relative 'tokenizer/main'
Douglas G. Allen
sumber
1

Saya menggunakan jruby-1.7.4 untuk mengkompilasi kode ruby ​​saya.

require 'roman-numerals.rb' 

adalah kode yang melemparkan kesalahan di bawah ini.

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

Saya menghapus rb dari keharusan dan memberi

require 'roman-numerals' 

Itu bekerja dengan baik.

Ananth Srinivasan
sumber
1

Bagi mereka yang benar-benar yakin jalur relatif mereka benar, masalah saya adalah bahwa file saya tidak memiliki .rbekstensi! (Meskipun saya dulu RubyMinemembuat file dan memilihnya sebagai file yang sedang Rubydibuat.)

Periksa ekstensi file pada file Anda!

Andy Barnett
sumber
1

Bagaimana dengan memasukkan direktori saat ini di jalur pencarian?

ruby -I. main.rb
Hans-J. Schmid
sumber
0

Masalahnya adalah itu requiretidak memuat dari direktori saat ini. Ini adalah apa yang saya pikirkan, tetapi kemudian saya menemukan utas ini . Misalnya saya mencoba kode berikut:

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>'

Seperti dapat dilihat membaca file ok, tapi saya tidak bisa memerlukannya (path tidak dikenali). dan begini kode yang berfungsi:

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

Seperti yang Anda lihat jika Anda menentukan path lengkap file dimuat dengan benar.

Boris Strandjev
sumber
1
Ini masalah pilihan. Saya pribadi selalu suka menguji apa yang saya lakukan di konsol interaktif. Saya membuat banyak kesalahan, dan saya suka mendapat umpan balik interaktif.
Boris Strandjev
0

Pertama:

$ sudo gem install colored2

Dan, Anda harus memasukkan kata sandi Anda

Kemudian :

$ sudo gem update --system  

Muncul Memperbarui rubygems-update ERROR: Ketika menjalankan permata ... (OpenSSL :: SSL :: SSLError) nama host "gems.ruby-china.org" tidak cocok dengan sertifikat server

Kemudian:

$  rvm -v
$ rvm get head

Terakhir Bahasa apa yang ingin Anda gunakan ?? [Swift / ObjC]

ObjC

Apakah Anda ingin menyertakan aplikasi demo dengan perpustakaan Anda? [ Ya Tidak ]

Iya

Kerangka kerja pengujian mana yang akan Anda gunakan? [Specta / Kiwi / Tidak Ada]

Tidak ada

Apakah Anda ingin melakukan pengujian berbasis tampilan? [ Ya Tidak ]

Tidak

Apa awalan kelas Anda?

XMG

Menjalankan pemasangan pod di perpustakaan baru Anda.

Lxt_91424
sumber
-2

Anda harus memberi jalan. Setidaknya Anda harus memberikan path dari direktori saat ini. Pasti akan berhasil. ./nama file

Dittu Joju
sumber
Untuk lebih jelasnya, saya pikir Anda harus memberikan bagian berulang dari kode di sini dengan perbaikannya. Suara turun bukan milikku
Rohit Gupta