connelblaze
connelblaze

Reputation: 793

cannot load such file -- write_file

I'm new to Ruby. I just started so it's strange to me because I am coming from a Java & C# background.

write_file.rb contains:

class Write_file

  def write_method(title, text)

    @title = title+".txt"
    my_file = File.new(@title, 'w')
    #my_file.close
    puts "Creating file..."

    @text = text
    my_file = File.open(@title, 'w'){|file|
      file.puts @text
    }
    puts "done!"
  end
end

read_file.rb contains:

class Read_file
  def read_method(title)
    file = title + ".txt"
    File.readlines(file).each do |line|
      puts line
    end
  end
end

write_read.rb contains:

require "write_file"
require "read_file"
puts "Choose what you want to do :\n1. Write a file\n2. Read a file"
input = gets.to_i
if input.equals? 1
  puts "Enter name of file here:"
  title = gets.chomp
  puts "Enter text here:"
  text =gets.chomp
  x = Write_file.new
  x.write_method(title,text)
  puts x
elsif input.equals? 2
  puts "Enter name of file to read"
  file = gets.chomp
  rid = Read_file.new
  rid.read_method(file)
  puts rid
else puts "Invalid selection"
end

But I get the following error:

/usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- write_file (LoadError)                                            
    from /usr/local/rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'                                                                                
    from /home/ubuntu/workspace/ruby/write_read.rb:1:in `<main>'                                 

Upvotes: 2

Views: 621

Answers (2)

the Tin Man
the Tin Man

Reputation: 160553

There are several things you're not doing correctly.

Your error is a result of not understanding how Ruby can load files to be included into your script.

require, by default, will load files from Ruby's core and standard libraries and any gems you've installed. It can also use absolute and relative paths. Sometimes people will push local directories into the search path to make it possible for require to find local files, but that's not necessary or particularly recommended; The reasons why involve security for your script and led to the creation of require_relative.

require_relative, by default, will load files from the current directory, or other directories if you've specified a relative path to the file. In your code you should use require_relative to load write_file.

Moving on:

  • Write_file and Read_file are not good names for classes. We use CamelCase for class names, so WriteFile or ReadFile would be more appropriate, but classes are things, not actions, so File would be appropriate (if it wasn't already taken by the built-in File class) and inside the class would be write and read methods (which again already exist in the built-in File class).
  • Your use of instance variables like @title isn't correct. Consider an instance variable to be a global variable accessible by an instance of the class only inside its instance. You're using @title only within a given method, not outside of it, so a local variable title would be appropriate. Variable scope, their visibility within blocks, classes, methods, etc., is confusing at first so spend time up front getting a good handle on them or you'll be spewing variables all over and running into problems with them being stomped on.

Upvotes: 1

ReggieB
ReggieB

Reputation: 8212

When you run a script from the command line, you'll typically us a command like: ruby my_script.rb. When you do that you are running that script in the context of the ruby executable, and any paths need to be accessible to the the ruby executable. Gems etc. are registered with the executable, so their paths can be accessed reasonably easily. But other scripts that you write won't be known to the ruby executable, and therefore won't be accessible via a simple require <filename>.

So to get around this you can do a couple of thing. One is to do this:

require File.expand_path('write_file', File.dirname(__FILE__))

That tells ruby that the file's location is relative to the script file being run.

However, since ruby 1.9.3 there is a simpler solution; use require_relative. This is the equivalent to the expand_path code above:

require_relative 'write_file'

Upvotes: 1

Related Questions