5 Random Ruby Tips - Sep 2015 (SRB Meetup)

37ef5e5ddd4b05465000dbea5d4b22e2?s=47 Huiming Teo
September 29, 2015

5 Random Ruby Tips - Sep 2015 (SRB Meetup)

37ef5e5ddd4b05465000dbea5d4b22e2?s=128

Huiming Teo

September 29, 2015
Tweet

Transcript

  1. 5 random ruby tips Huiming @ ReferralCandy SRB Meetup (Sep

    2015)
  2. Contributed by, ReferralCandy Engineering Team (during Thursday Group Code Review

    session) • https://github.com/GreenRecycleBin • https://github.com/jcwilk • https://github.com/pest-control • https://github.com/shiawuen • https://github.com/teohm
  3. Ruby Tips 1: ActiveRecord #update / #update! # Option 1:

    # Check returned value if model.update # update successful else # update failed end # Option 2: # Rescue raised error begin model.update! rescue => e # update failed end
  4. Ruby Tips 2: Open3#popen3 deadlock Open3.popen3("run_cli_program") do |stdin, stdout, stderr,

    wait_thr| stderr.read # try to read stderr first, blocked stdout.read # but too much output to stdout, # exceeds fixed length buffer, # causing deadlock end
  5. Ruby Tips 2: Open3#popen3 deadlock You should be careful to

    avoid deadlocks. Since pipes are fixed length buffers, ::popen3(“prog”) {|i, o, e, t| o.read } deadlocks if the program generates too much output on stderr. You should read stdout and stderr simultaneously (using threads or IO.select). However, if you don’t need stderr output, you can use :: popen2. If merged stdout and stderr output is not a problem, you can use :: popen2e. If you really need stdout and stderr output as separate strings, you can consider ::capture3. RubyDoc - Open3#popen3
  6. Ruby Tips 2: Open3#popen3 deadlock # Better Option - Open3#capture3

    # It blocks until out, err, status are collected out, err, status = Open3.capture3("run_cli_program") out[0] # first line from stdout err[0] # first line from stderr
  7. Ruby Tips 3: 1000 char limit per line in SMTP

    # Rich HTML email has unexpected.. line breaks and space, # causing the styling to break ... <a id="foobar" style="color: #666; .... font-si ze: 23px;">Foo Bar</a> ... More details: Quoted-printable – crossing the 1000 character SMTP barrier
  8. Ruby Tips 3: 1000 char limit per line in SMTP

    # mail gem by default, Content-Transfer-Type: 7bit mail = Mail.new { html_part do content_type 'text/html; charset=UTF-8' body html_email_content end }
  9. Ruby Tips 3: 1000 char limit per line in SMTP

    # Solution: use Content-Transfer-Type: quoted-printable # to encode HTML content properly with 76 chars per line mail = Mail.new { html_part do content_transfer_type 'quoted-printable' content_type 'text/html; charset=UTF-8' body html_email_content end }
  10. Ruby Tips 4: Fake service pattern in tests class Service

    def do_stuff ... # calling external service CustomerIO::Client.new.track(event) ... end end
  11. Ruby Tips 4: Fake service pattern in tests module Fakes

    class CustomerIoClient attr_accessor :events def initialize @tracks = [] end def track(event) self.events << event end end end
  12. Ruby Tips 4: Fake service pattern in tests describe '#do_stuff'

    do let(:faker) { Fakes::CustomerIoClient.new } before do allow(CustomerIO::Client).to receive(:new) { faker } end it 'sends correct stuff' do service.do_stuff expect(faker.events).to include expected_event end end
  13. Ruby Tips 5: include_examples vs. it_behaves_like 1 shared_examples 'shared tests'

    do 2 it 'do test 1' 3 it 'do test 2' 4 end 5 6 describe 'foo' do 7 include_examples 'shared tests' 8 it 'do test 3' 9 end $ be rspec spec/foo_spec.rb:7 -fd Run options: include {:locations=>{". /spec/foo_spec.rb"=>[7]}} foo do test 1 (PENDING: Not yet implemented) do test 2 (PENDING: Not yet implemented) do test 3 (PENDING: Not yet implemented)
  14. Ruby Tips 5: include_examples vs. it_behaves_like 1 shared_examples 'shared tests'

    do 2 it 'do test 1' 3 it 'do test 2' 4 end 5 6 describe 'foo' do 7 it_behaves_like 'shared tests' 8 it 'do test 3' 9 end $ be rspec spec/foo_spec.rb:7 -fd Run options: include {:locations=>{". /spec/foo_spec.rb"=>[7]}} foo do test 1 (PENDING: Not yet implemented) do test 2 (PENDING: Not yet implemented)