简体   繁体   中英

Ruby and File.read

I am building a build automation script for my javascripts. I've never used File.read before, but I've decided to give it a try, since it saves a line of code.

So here is my code:

require "uglifier"
require "debugger"

@buffer = ""

# read contents of javscripts
%w{crypto/sjcl.js miner.js}.each do |filename|
  debugger
  File.read(filename) do |content|
    @buffer += content
  end
end

# compress javascripts
@buffer = Uglifier.compile(@buffer)

# TODO insert js in html

# build the html file
File.open("../server/index.html", "w") do |file|
  file.write @buffer
end

But, it doesn't work. @buffer is always empty.

Here is the debugging process:

(rdb:1) pp filename
"crypto/sjcl.js"
(rdb:1) l
[4, 13] in build_script.rb
   4  @buffer = ""
   5  
   6  # read contents of javscripts
   7  %w{crypto/sjcl.js miner.js}.each do |filename|
   8    debugger
=> 9    File.read(filename) do |content|
   10      @buffer += content
   11    end
   12  end
   13  
(rdb:1) irb
2.0.0-p0 :001 > File.read(filename){ |c| p c }
 => "...very long javascript file content here..."

As you can see, in the irb , File.read works fine. If I put debugger breakpoint within the File.read block however, it never breaks into debugger. Which means the block itself is never executed?

Also, I've checked the documentation, and File.read is mentioned nowhere. http://ruby-doc.org/core-2.0/File.html

Should I just ditch it, or am I doing something wrong?

%w{crypto/sjcl.js miner.js}.each do |filename|
  File.open(filename, 'r') do |file|
    @buffer << file.read
  end
end

This works just fine. However I'm still curious whats up with File.read

File.read doesn't accept a block, it returns the contents of the file as a String. You need to do:

@buffer += File.read(filename)

The reason debugger shows the contents is because it prints the return value of the function call.

Now, for some solicited advice, if you don't mind:

  1. There's no need of doing @buffer , you can simply use buffer
  2. Instead of var += "string" , you can do var << string . + creates a new String object, while << modifies it in-place, and thus is faster and efficient. You're mutating it anyways by doing += , so << will do the same thing.
  3. Instead of File.open then file.write , you can do File.write directly if using Ruby 2.0.

Your final code becomes (untested):

require "uglifier"
require "debugger"

buffer = ""

# read contents of javscripts
%w{crypto/sjcl.js miner.js}.each do |filename|
  buffer << File.read(filename)
end

# compress javascripts
buffer = Uglifier.compile(buffer)

# TODO insert js in html

# build the html file
File.write("../server/index.html", buffer)

If you'd like to make it more functional, I have more suggestions, please comment if you'd like some. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM