2
\$\begingroup\$

I have a method to upload a file using the Net::SFTP gem:

class Uploader
 def initialize(host,user,password)
 @host = host
 @user = user
 @password = password
 end
 def upload(local_file_path,remote_file_path)
 Net::SFTP.start(@host,@user,:password => @password) do |sftp|
 sftp.upload!(local_file_path,remote_file_path) do |event,uploader,*args|
 case event
 when :open
 Rails.logger("Starting upload...")
 when :finished
 Rails.logger("Finishing upload...")
 end
 end
 end
 end
end

The upload method seems rather large to me. Any suggestions on how I could split it up into smaller components?

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 15, 2015 at 21:14
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I don't see much reason to worry about this method's length. At least not right now - if you add more event handling, yeah, it might become a little cumbersome. But for what it does now, there's no pressing need to do anything.

I would recommend more whitespace, though. There's no reason to compress,every,line,that,has,commas,in,it. Just makes it harder to read.

I'm also fairly sure that the :finished event is actually called :finish

Structurally, just for the sake of it, you could do something like:

class Uploader
 attr_reader :host, :user, :password
 def initialize(host, user, password)
 @host = host
 @user = user
 @password = password
 end
 def upload(local_file_path, remote_file_path)
 Net::SFTP.start(host, user, password: password) do |sftp|
 sftp.upload!(local_file_path, remote_file_path) do |event, uploader, *args|
 send(event, uploader, *args) if respond_to?(event, true)
 end
 end
 end
 private
 def open(uploader, *args)
 Rails.logger("Starting upload...")
 end
 def close(uploader, *args)
 Rails.logger("Upload complete")
 end
 def finish(uploader, *args)
 Rails.logger("All done")
 end
end

Basically, we're handling events with methods instead of a case block. I've added the close method/event handler as an example.

answered Jan 15, 2015 at 22:20
\$\endgroup\$
1
\$\begingroup\$

The docs suggest creating a custom handler:

... you can create custom handler objects that respond to certain methods, and then pass your handler to the uploader:

class CustomHandler
 def on_open(uploader, file)
 puts "starting upload: #{file.local} -> #{file.remote} (#{file.size} bytes)"
 end
 def on_put(uploader, file, offset, data)
 puts "writing #{data.length} bytes to #{file.remote} starting at #{offset}"
 end
 def on_close(uploader, file)
 puts "finished with #{file.remote}"
 end
 def on_mkdir(uploader, path)
 puts "creating directory #{path}"
 end
 def on_finish(uploader)
 puts "all done!"
 end
end
sftp.upload!("local", "remote", :progress => CustomHandler.new)
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Oct 24, 2018 at 17:57
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.