Day 1 - Intro to Ruby
-
Upload
barry-jones -
Category
Internet
-
view
149 -
download
2
Transcript of Day 1 - Intro to Ruby
Welcome toRuby on Rails and PostgreSQL
Make sure things are installed
• Windows
– Vagrant
– Virtual Box
– Vagrantfile
• OSX
– Homebrew
• Everybody
– RVM
If you haven’t already installed these, go ahead and start them now… (links in Hipchat room)
COURSE INTRODUCTION
Why are we here exactly?
Who am I?
• I’m Barry Jones
• Application Developer since ’98
– Java, PHP, Groovy, Ruby, Perl, Python
– MySQL, PostgreSQL, SQL Server, Oracle, MongoDB
• Efficiency and infrastructure nut
• Believer in “right tool for the job”
– There is no silver bullet, programming is about tradeoffs
Why am I teaching this class?
• Learned Rails and PostgreSQL 2.5 years ago
How I learned?
• Took over a large perl to rails conversion post-launch
• It did not go well
• Took over the entire project without knowing Rails or PostgreSQL
• It was an interesting year
So why am I teaching this class?
Reason 1
• I wish it had been available for me
• Could have gotten up to speed much faster
Reason 2
• I wish it had been available for the contractors
• Could have avoided a slew of mistakes that I had to fix
How?
• Rails is great but…
• The community is largely driven by DHH who pushes doing everythingin Rails
• Rails is not the solution for everything
• Ruby isn’t perfect. It’s awesome…but not perfect
• PostgreSQL is great but…
• There is no “but”, PostgreSQL is just great
• But…if you don’t know why it’s great or how to use it you will tend to favor doing everything in Rails…
• Or adding in 3rd party systems you don’t need
Understanding these two things will…
• Give you amazing tools
• Help you work faster
• Help you solve more problems
• Keep you from creating Kool-Aid induced issues
Now…who are you people?
Introduce yourselves
• Name
• Where are you from?
• Quick professional overview
• What do you want to get out of this class?
• Favorite Movie
INTRO TO RUBY
What do we look for in a language?
• Balance– Can it do what I need it to do?
• Web: Ruby/Python/PHP/Perl/Java/C#/C/C++
– Efficient to develop with it?• Ruby/Python/PHP
– Libraries/tools/ecosystem to avoid reinventing the wheel?• Ruby/Python/PHP/Java/Perl
– Is it fast?• Ruby/Python/Java/C#/C/C++
– Is it stable?• Ruby/Python/PHP/Perl/Java/C#/C/C++
– Do other developers use it?• At my company? In the area? Globally?
– Cost effective?• Ruby/Python/PHP/Perl/C/C++
– Can it handle my architectural approach well?• Ruby/Python/Java/C# handle just about everything• CGI languages (PHP/Perl/C/C++) are very bad fits for frameworks, long polling, evented programming
– Will it scale?• Yes. This is a subjective question because web servers scale horizontally naturally
– Will my boss let me use it?• .NET shop? C#• Java shop? Java (Groovy, Clojure, Scala), jRuby, jython• *nix shop? Ruby, Python, Perl, PHP, C, C++
• Probable Winners: Ruby and Python
What stands out about Ruby?
• Malleability– Everything is an object
– Objects can be monkey patched
• Great for writing Domain Specific Languages– Puppet
– Chef
– Capistrano
– Rails
“this is a string object”.length
class String
def palindrome?
self == self.reverse
end
end
“radar”.palindrome?
How is monkey patching good?
• Rails adds web specific capabilities to Ruby– “ “.blank? == true
• Makes using 3rd party libraries much easier– Aspect Oriented Development
• Not dependent on built in hooks
– Queued processingrecord = Record.find(id)
record.delay.some_intense_logic
• DelayedJob• Resque• Sidekiq• Stalker• Que• QueueClassic
– Cross integrationsEmail.deliver
• MailHopper – Automatically deliver all email in the background• Gems that specifically enhance other gems
How is monkey patching…bad?
• If any behavior is modified by a monkey patch there is a chance something will break
• On a positive note, if you’re writing tests and following TDD or BDD the tests should catch any problems
• On another positive note, the ruby community is very big on testing
Why was Ruby created?
• Created by Yukirio Matsumoto
• "I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.”
• "I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.”– Google Tech Talk in 2008
Ruby Version Manager
• cd into directory autoselects correct version of ruby and gemset
• Makes running multiple projects with multiple versions of ruby and gem dependencies on one machine dead simple
.rvmrc file
rvm rubytype-version-patch@gemset
Examples:
rvm ruby-1.9.3-p327@myproject
rvm jruby-1.7.4@myjrubyproject
rvm ree-1.8.7@oldproject
.ruby-version file
ruby-2.1.2
.ruby-gemset file
myproject
Bundler and Gemfile
$ bundle install
Using rake (10.0.4)
Using i18n (0.6.1)
Using multi_json (1.7.2)
Using activesupport (3.2.13)
Using builder (3.0.4)
Using activemodel (3.2.13)
Using erubis (2.7.0)
Using journey (1.0.4)
Using rack (1.4.5)
Using rack-cache (1.2)
Using rack-test (0.6.2)
…
Your bundle is complete! Use `bundle show
[gemname]` to see where a bundled gem is
installed.
source 'https://rubygems.org'
source 'http://gems.github.com'
# Application infrastructure
gem 'rails', '3.2.13'
gem 'devise'
gem 'simple_form'
gem 'slim'
gem 'activerecord-jdbc-adapter’
gem 'activerecord-jdbcpostgresql-
adapter'
gem 'jdbc-postgres'
gem 'jruby-openssl'
gem 'jquery-rails'
gem 'torquebox', '2.3.0'
gem 'torquebox-server', '~> 2.3.0'
Foreman
Not Ruby specific but written in ruby
Used with Heroku
Drop in a Procfile
$ foreman start
CTRL + C to stop everything
Procfile
web: bundle exec thin start -p $PORT
worker: bundle exec rake resque:work QUEUE=*
clock: bundle exec rake resque:scheduler
Basic Syntax / Standards
• Indents are 2 spaces• Methods can include ! or ? Characters
– ! Indicates the object will be modified• Change a String rather than returning a changed String• Sort an array rather than returning a sorted copy
– ? Indicates a boolean return• Rather than including “is” or “has” as part of a method name, use a ?• .palindrome? VS is_palindrome
• Methods with arguments do not HAVE to include parentheses around them– User.new(“Bob”)– User.new “Bob”
• There are no ++ or -- options. Use += 1 or -= 1 for equivalent• foo ||= “bar” means
– If foo is not initialized or false, set to “bar”– foo || foo = “bar”
• to_s = String, to_i = Integer, to_f = Float, to_sym = Symbol• :bob.to_s == “bob”, “bob”.to_sym == :bob• Use :bob over and over, same object is used vs “bob” which creates a String• Embed code in strings with “My name is #{name} the extraordinary!”
Object Methods
Instance Method
• def leopard?false
end
Class Method
• def self.leopard?false
end
Implicit return- Last line is automatically returned
Explicit returns - return false
Object Variables
Instance Variable
• @my_variable = ‘bob’
Class Variable
• @@my_variable = ‘bob’
Accessors (get/set)
• class AccessorDemoattr_accessor :helloattr_reader :helloattr_writer :hello
def initialize(hello = “World”)# Constructor btw @hello = hello
endend
Error Handling
• raise (throw)
• regin (try)
• rescue (catch)
• Exception vsStandardError
beginraise “Whoops”
rescue StandardError => eputs e.message
elseputs “All is well”
end
Error Handling Shorthand
• def risky_method!raise “OMG!” if epic_fail?
end
risky_method! rescue “epic fail…smh”
• raise and rescue default to StandardError
• Methods automatically encompass a “begin” wrapper
The *splat operator
Method Definitionsdef say(what, *people)people.each do|person| puts "#{person}: #{what}”
endend
say "Hello!", "Alice", "Bob", "Carl"# Alice: Hello!# Bob: Hello!# Carl: Hello!
Method Callspeople = ["Rudy", "Sarah", "Thomas"]say "Howdy!", *people# Rudy: Howdy!# Sarah: Howdy!# Thomas: Howdy!
def add(a,b)a + b
end
pair = [3,7]add *pair# 7
Variable Assignment from Arrays
first, *list = [1,2,3,4] # first= 1, list= [2,3,4]*list, last = [1,2,3,4] # list= [1,2,3], last= 4first, *center, last = [1,2,3,4] # first= 1, center= [2,3], last=4
Hashes
• { :name => ‘Bob’, :rank => :general, :sn => 1 }• { name: ‘Bob’, rank: :general, sn: 1 }• person[:name]• HashWithIndifferentAccess: person[‘name’]
• def some_method(hash_opts)# do things…
end
some_method(name: ‘Bob’, sn: 1)
Blocks and Yields
def my_method(&block)puts “Before block”
&block.call
puts “After block”
&block.call #again
end
my_method doputs “I like to do things!”
end
def my_methodputs “Before block”
yieldputs “After block”
yield # Call it all you want
end
my_method doputs “I like to do things!”
end
find_each
Person.find_each(:conditions => "age > 21") do |person|person.party_all_night!
end
def find_each(options = {})find_in_batches(options) do |records|records.each { |record| yield record }
end
selfend
if / else / elsif / unless
• if true# do things
elsif 5 # do other things
else# do final things
end
• unless true# do some stuff
end
• Trailing syntax
puts “I see bob!” if bob?
puts “No bob!” if !bob?
puts “No bob!” unless bob?
Range operator
(-1..-5).to_a #=> []
(-5..-1).to_a #=> [-5, -4, -3, -2, -1]
('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a #=> ["a", "b", "c", "d"]
Switch (Case/When)
• case awhen 1..5
# stuffwhen String# stuff
when /regexmatches/# stuff
when 42# stuff
else# stuff
end
Mixins
module Persistencedef load sFileName
puts "load code to read #{sFileName} contents into my_data"end
def save sFileNameputs "Uber code to persist #{@my_data} to #{sFileName}"
endend
class BrandNewClassinclude Persistenceattr_accessor :my_data
def data=(someData)@my_data = someData
endend
b = BrandNewClass.newb.data = "My pwd"b.save "MyFile.secret"b.load "MyFile.secret"
Pry
def some_methodbinding.pry # Execution will stop here.puts 'Hello World' # Run 'step' or 'next' in the console to move here.
end
• step: Step execution into the next line or method. Takes an optional numeric argument to step multiple times. Aliased to s
• next: Step over to the next line within the same frame. Also takes an optional numeric argument to step multiple lines. Aliased to n
• finish: Execute until current stack frame returns. Aliased to f
• continue: Continue program execution and end the Pry session. Aliased to c
RSpec
• before dosubject.stub(:big_calculation) { true }
end
it “should return a value that does things” subject.big_calculation.should be_true
end
Try it out!
• Create a gemset
• Create a Gemfile
• Install a gem
• Create a ruby file with some experimental code
• Open a Ruby console
• Experiment with classes and structures presented here