Skip to content

Instantly share code, notes, and snippets.

@DixcomWeb
Forked from afair/confident.rb
Created May 21, 2011 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DixcomWeb/984667 to your computer and use it in GitHub Desktop.
Save DixcomWeb/984667 to your computer and use it in GitHub Desktop.
Notes on Advi Grimm's "Confident Code" talk
# http://avdi.org/talks/confident-code-2010-01-12/confident-code.html
# Narrative structure: Four Parts
#==========================================================
# Gather input:
# Coerce
param.to_s #to_i #to_sym Array() ... use liberally!
messages = Array(messages)
# Decorators
destination = WithPath.new(options[:out]).path
# Reject
raise Exception, message, caller unless value
# Guard clause
return "" if message.nil?
# Ignore
# Null Object, responds to any message with nil or itself
#----------------------------------------------------------
# Avoid nil!!!
# It means too many things
# Error
# Missing Data
# Flag for "default behavior"
# Uninitialized variable
# Use Hash#fetch with block for when value not found
{}.fetch(:width) # =>
# ~> -:7:in `fetch': key not found (IndexError)
{}.fetch(:width) { 40 } # => 40
{:width => nil}.fetch(:width) {40} # => nil
{:width => false}.fetch(:width) {40} # => false
{:width => 29}.fetch(:width) {40} # => 29
# Custom error
opt = {}.fetch(:required_opt) do
raise ArgumentError, "Missing option!"
end
def initialize(logger=NullObject.new)
@logger = logger
end
# Stub Object Default
# $? is either nil or a Process::Status object
def check_child_exit_status!(status=$?)
status ||= OpenStruct.new(:exitstatus => 0)
unless [0,172].include?(status.exitstatus)
raise ArgumentError,
"Command exited with status #{status.exitstatus.status}"
end
end
#==========================================================
# Perform work
# Reserve conditionals for business logic
if post.published? # => Business Login
if post # => Not
# Isolate error/input handling from program flow
# Iteration over singular objects... jQuery example
# $("div.notLongForThisWorld").fadeOut().addClass("removed");
#==========================================================
# Deliver results
#==========================================================
# Handle errors
def method()
# logic
rescue => error
# error handing at the end
end
# Bouncer Method
def check_child_exit_status
result = yield
status = $? || OpenStruct.new(:exitstatus => 0)
unless [0,172].include?(status.exitstatus)
raise ArgumentError,
"Command exited with status #{status.exitstatus}"
end
result
end
check_child_exit_status {
@io_class.popen(command, "w+") # ...
}
# Checked Method
def checked_popen(command, mode, fail_action)
check_child_exit_status do
@io_class.popen(command, "w+") do |process|
yield(process)
end
end
rescue Errno::EPIPE
fail_action.call
end
checked_popen(command, "w+", lambda{message}) do |process|
# ...
end
#-------------------------------------------
# Array() The "arrayification operator"
Array([1,2,3]) # => [1, 2, 3]
Array("foo") # => ["foo"]
Array(nil) # => []
# Gotcha:
Array("foo\nbar") # => ["foo\n", "bar"]
#----------------------------------------------------------
# Decorator
require 'delegate'
# ...
class WithPath < SimpleDelegator
def path
case __getobj__
when File then super
when nil then "return value"
else inspect
end
end
end
destination = WithPath.new(options[:out]).path
#----------------------------------------------------------
# A Basic Null Object
# - Returning self lets us nullify chains of calls
class NullObject
def initialize
@origin = caller.first ### SETS ORIGIN FOR INSPECT INFO
end
def method_missing(*args, &block)
self
end
def nil?; true; end
end
def Maybe(value)
value.nil? ? NullObject.new : value
end
if options[:out]
options[:out] << output
end
Maybe(options[:out]) << output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment