BRIAN SHIRAI @brixen https://speakerdeck.com/brixen/types-as-premature-optimization
- Peanut butter jelly sandwich as an example
- Problems
- Under-specified
- Imperative
- Repetitive
- Not abstract
- *LTR
- Purely functional peanut butter & jelly sandwich
- General purpose
- We don't learn from failure
- We learn from other's failure
- Perception & Cognition, are they reality?
- How to Keep Your Neighbors in Order (paper)
- Eight fallacies of programming
- Same scale
- Same risk
- Same cost (N * klocks = $)
- Same granularity (Everything is an object, function)
- Same abstraction (Compile at one point in time)
- Same temporality
- Same order (z => z^2 +c)
- study of chaos (http://en.wikipedia.org/wiki/Chaos_theory)
- barnsley fern
- General purpose
- nil is not null (it's an object!)
# the solution to nil class problem
class NilClass
def method_missing(*)
self
end
end
# functions in ruby?
module Kernel
...
module_function
end
# specify types
fun add(a: int, b: int)
a + b
end
- https://www.destroyallsoftware.com/screencasts
- The Power of Interoperability: Why Objects Are Inevitable - Jonathan Aldrich
- Ruby is good for
- parsers, GCs
- General purpose is one of the big problems of programming
- Try Rubinius (https://github.com/rubinius/rubinius)
No [corporation] can stop an idea whose time has come. - Victor Hugo Complain about the way other people make software by making software. - ?
ERIK MICHAELS-OBER @sferik https://speakerdeck.com/sferik/writing-fast-ruby
In establishing engineering disciplines a 12% improvement, easily obtained, is never considered marginal, and I believe ... - Don Knuth, December, 1974 Ruby is designed to make programmers happy. - Matz
Levels of Optimization Design : Architecture and algorithms (e.g. n + 1 queries)
Source : Writing fast code
Build
: Setting build flags (e.g. ./configure
)
Compile : mrbc, jrubyc, rbx compile
Runtime
: Thanks Matz & Koichi (e.g. RUBY_GC_MALLOC_LIMIT
)
Proc#call versus yield
def slow(&block)
block.call
end
# Over 5X faster!
def fast
yield
end
Block versus Symbol#to_proc
(1..100).map { |i| i.to_s }
(1..100).map(&:to_s) # 20% faster!
Enumerable#map and Array#flatten versus Enumerable#flat_map
enum.map do
# do something
end.flatten(1)
# Over 4.5X faster!
enum.flat_map do
# do something
end
Hash#merge versus Hash#merge!
enum.inject({}) do |h, e|
h.merge(e => e)
end
# Over 3X faster!
enum.inject({}) do |h, e|
h.merge!(e => e)
end
Hash#merge! versus Hash#[]=
enum.each_with_object({}) do |e, h|
h.merge!(e => e)
end
# Over 2X faster!
enum.each_with_object({}) do |e, h|
h[e] = e
end
Hash#fetch versus Hash#fetch with block
{:bar => :uco}.fetch(:bar, (0..9).to_a)
{:bar => :uco}.fetch(:bar) { (0..9).to_a } # Over 2X faster!
String#gsub versus String#sub
'http://baruco.org/'.gsub('http://', 'https://')
'http://baruco.org/'.sub('http://', 'https://') # 50% faster!
String#gsub versus String#tr
'slug from title'.gsub(' ', '_')
'slug from title'.tr(' ', '_') # Over 5X faster!
Parallel vs sequential assignment
a, b = 1, 2
# 40% faster!
a = 1
b = 2
Using exceptions for control flow
begin
bar
rescue NoMethodError
'uco!'
end
# Over 10X faster!
if respond_to?(:bar)
bar
else
'uco!'
end
while loops versus Array#each_with_index
array.each_with_index do |number, index|
# do something with number and index
end
# Over 80% faster
while index < array.size
# do something with array[index] and index
index += 1
end
Double pipe? Inlining? Mutability? Immutable data types in Ruby
JASON R. CLARK @jasonrclark https://speakerdeck.com/jasonrclark/spelunking-in-ruby
Spelunking => Cave exploration
Built-in - put your initials in puts or prys - use custom variables $bedug
# show even swallowed exceptions
$ ruby -d deal_with_it.rb
#
$1
Gems
# open gem
$ EDITOR=vim bundle open newrelic_rpm
# open gem
$ gem open newrelic_rpm
# restore gems
$ gem pristine newrelic_rpm
Others
# hometown
Hometown.watch(::Thread)
t = Thread.new do
loop {}
end
p Hometown.for(t) # returns Hometown::Trace...
# pry
@tool = "crowbar"
def crowbar
bar_like = true
binding.pry
end
# pry debugging ls, whereami, etc.
$ gem install pry-byebug
$ gem install pry-debugger
$ gem install pry-nav # next, step, continue, etc.
$ gem install pry-stack_explorer # up, show-stack
$ ~/.pryrc
Pry::Commands.command... # https://github.com/pry/pry/issues/607
Tools
- jruby
- rubinius
# sample debug
debug> break Object.my_message # supports breakpoints
# rubinius debugging
$ ruby -Xdebug rbx.rb
- gdb
require 'thread'
puts Process.pid
m1 = Mutex.new
m2 = Mutex.new
Thread.new do
loop do
...
end
end
t = []
t << Thread.new do
m1.lock; sleep 1; m2.lock
end
t << Thread.new do
m2.lock; sleep 1; m1.lock
end
t { |ts| ts.join }
puts "Done!" # deadlock! never reaches here
$ ruby deadlock.rb
2796
# use dgb
$ sudo gdb
$ attach 2796
# start debugging!
(gdb) thread apply all backtrace
# tons of logs... notice rb_mutex_lock
(gdb) call (void)rb_backtrace()
(gdb) call (void)fflush(0)
$ ~/.gdbinit
define ruby_eval
call(rb_p(rb_eval_string_pro...
end
- strace
- rbtrace (https://github.com/tmm1/rbtrace)
$ rbtrace -p <PID> --firehose
# other options
$ rbtrace -p slow=<N>
$ rbtrace -p <PID> --methods "Kernel#sleep" "Proc#call"
$ rbtrace -p <PID> --gc
$ rbtrace -p <PID> -c activerecord io
slides on http://jasonrclark.com/debug
EVAN PHOENIX @evanphx https://speakerdeck.com/evanphx/services-services-services
- Small things?
- Structure an application as a composition of services
- Isolate functionality within separate code bases
- Profit?
- What size is "micro"
- "single data type"
- User service
- "a single operation"
- Login service
- "logical group"
- "single data type"
Benefits
- Responsibility isolation
- aka as "Surface Area"
- It's the behavior of a certain app within the domain
- As small as possible, no smaller
- Keeps teams in control of their own destiny
- Forced discipline
- We're lazy. It's ok
- We look for shortcuts and hacks, that's why we're programmers
- Service boundaries keep us honest
- Constraints allow for innovation, embrace them
- Separate velocity vectors
- Unique services have their own schedules
- Team A doesn't need to wait on Team B to finish a feature
- High, safe velocity == happy programmers
Pitfalls
- Don't share ActiveRecord models between Services (SMP - Shared Model Pain)
- Different services will want different "helpers"
- The Breakup Redux
- Fix "touchers"
- Whiteboard architecture?
- Deployment
- N apps can't mean N deployment mechanisms
- Each service will have differences
- Better to use fit apps to deployment than deployment to apps
- Unify deployment across all apps!
- Solutions
- Capistrano
- PaaS
- One configuration system
- Use ENV vars
- etc.
- Do a fire drill once a month - pretend that the site is down
Inter Service Communication The Network is the Computer
Tips
- Expect Failure
- Tracing (logging?)
- How & What
- Don't argue over how X talks to Y
- Have one convention that spans all services
- Build tooling that exercises these conventions
- This should eventually be second nature to everyone
How?
- RPC
- Good example is finagle (https://twitter.github.io/finagle/)
- testing? Normal mocking, that's it.
- REST / Documents
- JSON over HTTP from REST endpoints
- very flexible => flexible is the productivity killer
- standardize! don't leave room for flexibility
- Use something like ActiveResource?
- testing? VCR (https://github.com/vcr/vcr)
- JSON over HTTP from REST endpoints
- Message passing
- Make communication async
- Allows for unique communication patterns
- Broadcast
- Pub/Sub
- SQS/SNS, RabbitMQ, etc.
- testing? Abstract away our broker
TOM STUART @tomstuart
Monads (http://en.wikipedia.org/wiki/Monad_(functional_programming))
- What is a stack?
- #push (value
- #pop
- #top
- #empty?
- different implementations
- Handling nil
- Rails'
try
- monkey patch
Object
andNilClass
- Rails'
class Optional
def and_then(&block) # formerly try
if value.nil
Optional.new(nil)
else
block.call(value)
end
end
end
Asynchronous code
GET https://api.github.com
GET https://api.github.com/orgs/ruby
GET https://api.github.com/orgs/ruby/repos
...
# Nobuyoshi Nakada
# snippet
class Eventually
def and_then(&block)
Eventually.new do |success|
...
end
end
Monads => abstract data type (Optional, Eventually, Many)
#and_then
.from_value
https://github.com/tomstuart/monads
MATT AIMONETTI @mattetti
- PBKDF2
- MessageEncryptor?
class ::Pwned
def mashalload(*args)
# drop table one by one
end
def marshal_dump; end
def by
"Eve"
end
end
session[:pwned] = ::Pwned.new
http://godoc.org/github.com/mattetti/goRailsYourself/crypto
EVIL TOM STUART @rentalcustard https://docs.google.com/presentation/d/1c3N5khQkVZotZrCR4PgIIGY3FSI10VRtNC5KRlPccT0/edit#slide=id.g38d3ec8ec_0114
Smalltalk
- Objects are classes
- Have a class
- Have local state
- Have methods
- (Polymorphic) message passing
- Blocks
- work like methods - can take values, take arguments
- Have access to variables in calling context
- ...
- Easy to understand from 3 concepts
1 == 2
ifTrue: [ Transcript show: "whoa" ]
ifFalse: [ Transcript show: "ok" ]
Lisp
- Functions
- Accept 0..n arguments
- Return values
- Eschew side effects
- Can be replaced with their result without changing meaning of program
- Values
- Macros
- Look like functions
- Operate on programs
- Have full access to the language
- Get expanded when used
- Special forms
- Have special syntax or evaluation rules
- Look to the programmer like functions
(defn new-if
[predicate then-clause else-clause]
(cond predicate then-clause
:else else-clause)
# using special form
(defn unless
[predicate then-clause else-clause]
(if (not predicate) then-clause
:else else-clause)
# using macro
(defmacro unless
[predicate then-clause else-clause]
`(if (not ~predicate)
~then-clause
~else-clause))
Shell
- commands
- Accept 0..* arguments
- Have an exit status between 0 and 255
- input to STDIN
- output to STDOUT
- errors to STDERR
- redirection based on exit status
- space-delimited arguments
if [ 1 -eq 2 ]
then
echo "whoa
fi
# snippet
$ man [
What do these languages have in common?
- Minimal
- Pure
- Not useful
Conclusion: Ruby uses all these concepts! What is Gyroscopic Precession?
JULIAN CHEAL @juliancheal
artoo
- Ruby on robots
- others
- cylon (http://cylonjs.com/)
- gobot (http://gobot.io/)
- rubyserial (https://github.com/hybridgroup/rubyserial)
- arduino
- digispark (http://digistump.com/products/1)
- sparkcore (https://www.spark.io/)
- beaglebone (http://beagleboard.org/bone)
- leapmotion (https://www.leapmotion.com/)
- ouya controller (http://shop.ouya.tv/products/ouya-controller)
guy used a dance mat to control a drone!!!