Skip to content

Instantly share code, notes, and snippets.

@raygervais
Last active July 7, 2019 22:04
Show Gist options
  • Select an option

  • Save raygervais/41d6071b27bb75ad7c620219993e84c9 to your computer and use it in GitHub Desktop.

Select an option

Save raygervais/41d6071b27bb75ad7c620219993e84c9 to your computer and use it in GitHub Desktop.
[Idiomatic Ruby] Pluralsight Course Explaining Better Ruby Idioms.
# Desired Behavior Module
# Unit Testing, Why and How
# MiniTest Example
class FizzBuzzTest < MiniTest::Test
def setup
@fizz_buzz = FizzBuzz.new
end
def test_three
assert_equal "1, 2, Fizz", @fizz_buzz.talk(3)
end
def test_five
assert_equal "1, 2, Fizz, 4, Buzz", @fizz_buzz.talk(5)
end
end
# Rspec Example (Same tests)
describe FizzBuzz do
it "replaces divisors of 3 with Fizz" do
expect(subject.talk(3)).to eq "1, 2, Fizz"
end
it "replaces divisors of 5 with Buzz" do
expect(subject.talk(5)).to eq "1, 2, Fizz, 4, Buzz"
end
end
# Out First Unit Test using MiniTest
# movie.rb
class Movie
# Built-in language getters and setters
attr_accessor :director, :genre, :release_date, :rotten_tomatoes, :title
def initialize(csv_row)
@director = csv_row[:director]
@genre = csv_row[:genre]
@title = csv_row[:title]
@release_date = csv_row[:release_date]
@rotten_tomatoes = csv_row[:rotten_tomatoes]
end
end
# movie_test.rb
require 'minitest/autorun'
require_relative 'movie'
class MovieTest < MiniTest::test
def setup
@movie = Movie.new({
:title => "Star Wars",
:genre => "Science Fiction",
:director => "George Lucas",
:release_date => "1977-05-25",
:rotten_tomatoes => "93",
})
end
def test_director
assert_equal "George Lucas", @movie.director
end
def test_genre
assert_equal "Science Fiction", @movie.genre
end
def test_rotten_tomatoes
assert_equal 93, @movie.rotten_tomatoes
end
def test_title
assert_equal "Star Wars", @movie.title
end
end
# DB Transaction Example
database.transaction do
from_account.subtract_balance(100.0)
to_account.add_balance(100.0)
end
# Async / Event Handler Example
button.on_click do |click_event|
create_new_user
end
# Functional Map Example
[1, 2, 3, 4].map do |int|
int * 2
end
# => 2, 4, 6, 8
# Predicate Method Conditional
# Predicate methods return only true or false,
# and have a question mark at the end.
if 4.even?
puts "4 is even"
else
puts "4 is odd"
end
# With if, you can also utilize `unless`
puts "4 is even" unless 4.odd?
# Conditional Assignments
def best_players
@best_players ||= begin
players = database.table(:players)
sorted = players.order(:points)
sorted.top(10)
end
end
# Common CSV Load into Rows Example
lines = File.open("movie.csv", "r") do |file_handle|
file_handle.readlines
end
rows = []
lines.each do |line|
# Chomp removes whitespace and newline characters
# << adds directly to array
rows << line.chomp.split(",")
end
# Adding Conditional to a block
movies = []
headers = nil
rows.each do |row|
# Only follow forward with logic if
# condition on the right is true (next / skip)
# Can be read as: `skip this row if it is empty`
next if row.empty?
if headers.nil?
header = row
else
# The zip method matches up values of the array
# from array passed in arguments: movies << headers.zip(row)
# For easier parsing, we'll utilize the Hash object to collapse the list of pairs.
movies << Hash(headers.zip(row))
end
end
put movies.first
# => ["Title" => "Star Wars Episode IV: A New Hope", "Release Date" => "1977-05-25", ... ]
require 'csv'
require_relative 'movies'
rows = CSV.read('movies.csv', :headers => true, headers_converter => :symbol, :skip_blanks => true)
# Map
movies = rows.map { |row| Movie.new(row) }
# Select
# In this example, get movies which contain a rotten tomatoes score.
with_rotten_scores = movies.select { |movie| movie.rotten_tomatoes > 0 }
# Reduce
average_rotten_score = with_rotten_scores.reduce(0.0) do |total, movie|
total + movie.rotten_tomatoes
end
# Group By
# In this example, get movie count released by month
movies_by_month = movies.group_by do |movie|
movie.release_date.strftime("%B")
end
# Ruby allows you to break an array in the map arguments
count_by_month = movies_by_month.map do |month, list|
[month, list.size]
end
# Sort By
# Using Ruby symbol to proc shortcut for last
count_by_month_sorted = count_by_month.sort_by(&:last).reverse
count_str = count_by_month.map { |pair| pair.join(": ")}.join("\n")
# Refactor (clean Up via chaining data methods)
count_by_month = movies.group_by do |movie|
movie.release_date.strftime("%B")
end.map do |month, list|
[month, list.size]
end.sort_by(&:last).reverse
count_str = count_by_month.map { |pair| pair.join(": ")}.join("\n")
# A few extras
[1,2,3,4,5].any?(&:even?) # => true
[1,2,3,4,5].all?(&:even?) # => false
[1,2,3,4,5].find(&:even?) # => 2
[1,2,3,4,5].reject(&:even?) # => 1,3,5
# Common Read File Pattern
file_handler = File.open(“movies.csv”, “r”)
begin
lines = file_handle.readlines
ensure
file_handler.close
end
#Idiomatic Lambda Read File Block
lines = File.open(“movies.csv”, “r”) do |file_handle|
file_handle.readlines
end
# Symbols are minimalistic strings in Ruby, often started with a `:`
# In some ways, symbols take the place of enums from other languages
# Playing off of movie CSV example above
require 'csv'
movies = CSV.read('movies.csv', :headers => true, headers_converter => :symbol, :skip_blanks => true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment