For comments, additional notes, corrections, etc. contact @cypher or mail me
Mislav Marohnić - Getting and loading code: current state of packaging & best practices
Loading code is simple
require loads stuff from the load path
once the file is located, it is loaded and executed
then gets added to loaded file to prevent it from being loaded twice
Rubygems hijacks require, and changes its behavior to support loading different versions of gems
Many gems use weird and unnecessary load/require practices
"'require rubygems' is a code smell… no it's always just wrong" - @rtomayko
Going manual:
- package your code in a .zip
- email it/upload to a server
- people download & extract code
- add lib dir to
$LOAD_PATH - they require your file and run their code
How to $LOAD_PATH
ruby -I "path/to/lib" myapp.rb
Initial $LOAD_PATH
Rubygems does the same thing as manual, just automated
Anatomy of a gem:
- metadata
- data
Alternatives:
- Geminstaller
- Bundler, rvm
- rip
- rpg
- Coral
rip & rpg are the interesting ones
Allow you to install gems without Rubygems
rpg designed to be fast
works completely without Rubygems
Coral can't do gems, installs everything from GitHub
Loading libs:
$ CORAL=hub@v1.2.0 irb -I~/Projects/Coral/lib -r coral
best practices:
- don't
require 'rubygems' - library code in "
lib", executable code in "bin" (more: "Ruby Packaging Standard" spec) - have a gemspec
- follow SemVer versioning policy
development mode:
- ruby irb with
irb -I lib - run executables with
RUBYLIB=lib bin/stuff - run tests with
ruby -I lib:test test/stuff/feature_test.rb
never get stuck
remember: it's just code
Florian Gilcher - Character encoding in Ruby 1.9
The Tower of Babel Compatibility Kit (TBCK)
On Encoding:
- Americans: I don't want to know
- Japanese: How can you not know?!
- Europeans: Unicode solves everything
Unicode/UTF-8 solves the problem for the western world
Ruby 1.9 solves this problem by (potentially) support all encodings
String is the biggest change in 1.9
- not Enumerable anymore
- list of characters, not bytes
- has attached Encoding
- Strings in multiple encodings can exist in same environment
String provides a way to convert between encodings using #encode and #encode!
Fails if the conversion is not possible
Strings of different encodings can be concatenated just fine if their encoding is compatible
Regular Expressions haves encodings as well, but can't change it
IO Objects have two special encodings:
external_encodingis the encoding of the input or output streaminternal_encodingis the encoding you want to use internally
String literals have the encoding of the source file they are in
Ruby assumes US-ASCII unless otherwise specified
#{- encoding=utf-8 -}
puts "Hello Wörld"
Enoding of IO Streams can be set using the mode string
File.open("test.txt", "r:US-ASCII") do |f|
# …
end
Internal and external Encoding can be set to defaults using Encoding.internal_encoding and Encoding.external_encoding
Also possible via cmd line switch: -Eex[:in]
What if you need to use String as a byte string?
Encoding.find('binary')
Two cases where you want to use binary:
- IO stream encoding is not known beforehand and must be determined
- reading input bytewise
String#force_encoding
If you are absolutely sure that the string has a diff encoding than it is flagged with, you can change it without conversion
think twice before doing this!
leads to hard to track down bugs
The three steps guide to complex IO in Ruby 1.9
- Read input, determine encoding
- Force encoding to the encoding the input is provided in
- Encode it to
interal_encoding
encode is also able to do error handling
Usage for Europeans
RUBYOPTS='-wKU'gives you best Unicode support for 1.8 and 1.9- Check IO libs wether they return sane strings
- …if not, complain to maintainer
Tips for library developers:
- Use US-ASCII, offload other stuff to localization files
- Expect UTF-8 and compatible encodings as input, provide output accordingly
- IO libs should be albe to read UTF-8, ISO-* and Windows-Encodings
- Docs are king
- Consider failing if
default_internaldoesn't match your expectations
Pitfalls
- Just because two strings look the same, but don't have to be (Unicode diacritic characters (?))
- Wrong console encoding (esp. Windows systems)
- Inability to guess source encoding
- source is already broken (e.g. database or database drivers)
Elise Huard - Evaluating quality of Rails codebase
Important when doing e.g. acquisitions
Maintenance for Freelancers
Where to start?
Try the app, see if it is buggy or slow
Rails version should be relatively recent
Check if plugins that are still alive (when was last commit, watchers on GitHub, etc.)
Run tests
Start with routes.rb
Routes are the first entry point into the app
Use railroad to get Models + their relationships as diagram
"Only two hard things in computer science: Cache invalidation and naming things" - Phil Karlton
names might not make sense to you in the beginning, but they should make sense to someone in the problem domain
Metrics: Know thine tools
When you get numbers, you should question them, e.g. where do they come from
LOC are not very expressive or useful
Use RubyParser and ParseTree to generate metrics, e.g. based on Symbolic Expressions (Sexps)
Flog: "The pain your code is in"
measures code complexity
Metrics:
- Very good methods < 20
- All right: < 50
Flay: Detect similar code
Saikuro: Cyclomatic Complexity
Doesn't use Ruby Parser, uses Ruby-Lex
Every keyword is interpreted into a state, which is then used to compute metrics
Good: Methods < 5
Roodi: Ruby Object Oriented Design Inferometer
Extensible
Reek: More OO-specific checks
rails_best_practices
Churn: Tells you which files have been changed most often
RCov: Executes tests, tracks the executed lines, reports test coverage
Good: 100% coverage
But 100% coverage doesn't mean you actually have tests covering the code
Heckle: Mutates code, sees if tests fail
metric_fu: runs all/most of these tools for you, presents nice overview
Check out the good stuff
What metrics don't tell you:
- Performance
- Wether it is readable
Matz - Keynote with Q&A about Ruby
"Meet the Rubyists"
This time, his suitcase was on time, but he missed his flight
Ruby Confs:
- EuRuKo in Europe
- RubyConf in US
- RubyKaigi in Japan
Other regional confs
Ruby Community is growing internationally
1993: 1 user 1995: 100 users 2000: 10.000 (Pickaxe released) 2005: 100.000 (Rails released)
Rails not first web framework, but much simpler & faster dev than before
2008: 1.000.000 (Gartner estimate) 2010: ? 2013: 4.000.000 (Gartner projection)
Community is growing quickly, lots of new people coming in
MINSWAN is greatest asset
Ruby community is known as being nice
Ruby may not be fastest, simplest or easiest, but we are nice
Something to be proud of
We have to keep the community nice
enlighten newcomers
What is nice?
def nice
brave &&
passionate &&
honest &&
respective
end
Brave:
- New technology is a risk
- Conservative people hate new tech
- But we love new tech
- We are brave
"From Java to Ruby" - book about adoption of a new technology
We are passionate
Hackers need to be passionate about tech (The Passionate Programmer)
We love Ruby
People who love Ruby are called Rubyists
Why do we love Ruby?
- We are hackers
- Hackers love freedom
- Hackers love power
- Ruby gives them
We are honest, fair, don't tell lies, don't distort reality
We respect others
"Although Ruby is my favorite language, I love all languages on the earth" (even PHP)
Other languages:
- envy them sometimes (features, libraries)
- learn from them
- steal ideas from them
Perl 6 has some stuff from Ruby
We respect other tools, languages, tech
We have great community
Most important factor
Lots of other OSS cannot have their community
we are very lucky
Once you have great community, most other problems become less important
We just need to survive
Many OSS projects don't survive long, get abandoned
OSS community is like a shark, have to keep moving to survive
If we keep moving forward, other problems will vanish
Ridiculous to choose language based on micro benchmark, but that's life
Ruby 1.9 is much faster, we can be even faster (JIT, optimization)
JRuby, Rubinius showing great promise
Ruby might be bad at threading (GIL, no multi-core boost)
We keep moving forward: MVM (Multiple VMs in a process), UNIX processes, better distributed frameworks, or event-driven frameworks
Ruby might not scale (memory consumption, slow interpreter, monkey patching)
We keep moving forward: Better GC, less memory consumption, better performance, scoping monkey patching (Ruby 2.0 issue)
Ruby might have other problems - but we keep moving forward
We don't have to worry, matz promises to move forward
Move forward together
Places to work on:
- Debug
- VM
- Libraries
- Frameworks
- Applications/Tools
- Documentation
We have very limited resources, esp. in ruby-core
Please work together
Q/A session
Q: Elaborate on Monkey Patching in Ruby 2.0
A: Replacing e.g. basic operators has huge side effects, so restrict monkey patches to a restrictive scope/namespace so they don't affect other code. Also add method combination/hook to make alias_method_chain obsolete
Q: Ruby 2.0 - when?
A: Still Vaporware, no promises about release date
Q: alias_method_chain - what about method signatures?
A: Ruby 2.0 will support keyword args, should mitigate problem
Q: Would you add static typing to ruby if you could start over?
A: Really hate to type data types. Haskell does great stuff, but don't want to do that
Q: Other languages you encourage people to learn/look at?
A: Languages that use other paradigms, so learn functional lang like Haskell, Clojure, Erlang. Prolog is also very different and interesting to learn.
Q: Alternative implementation that you like the most or see most potential
A: Rubinius has greatest potential, since it's mostly written in Ruby itself, inviting experimentation and easy rewriting. Mixed feeling about other implementations. MacRuby is great, has LLVM as backend, C Ruby have similar plan for backend, but MacRuby is basically a fork that does dev faster. But diversity is a good thing, moves things forward.
Q: What new features would you like to borrow from other languages for 2.0?
A: Monkey Patching stuff inspired by CLOS. Many ideas to steal. Have to design in a compatible way with existing Ruby system. Pattern matching, actors, STM, would be possible.
Q: alias_method_chain - when you include stuff in a class, new methods are put in between superclass and the actual class. Extend doesn't work that way, so can't use super to call original method. Solution for 2.0?
A: Have module stuff before stuff in the class, have something like prepend
Scott Chacon - Gittin' down to the plumbing
(Note: This talk is the same he gave at Scottish Ruby Conference 2010)
What Git is at the lowest possible level
Two levels of commands - plumbing and porcelain
porcelain is the stuff users see
plumbing is the lower-level stuff
Plumbing is not necessarily SCM-related
What is Git really?
Simple key/value content storage system
Directory snapshot storage system
History of directory snapshots system
put is hash-object
get is cat-file
(lots of low-level git commands here, watch the video)
Git storage is completely different from every other SCM, which all use file-based delta storage
Git is a synchable database of directory snapshots
Fits more scenarios other than source control
Example: Content Distribution System
Better & more efficient than rsync
Tomasz Stachewicz - Putting the static back into Ruby
'static' can mean:
- static code analysis
- static typing
focus on static code analysis
We do static code analysis when reading code
But computers are faster at it
Also great for answering "What should I refactor?"
use ParseTree, turns Ruby code into Sexps
Sexps were like the XML of the 70s
Example: Use ParseTree to find & remove unused methods
Problem with flog: simple/naive metrics are easy to cheat
just split stuff into methods
Should start with reek for static code analysis
fun idea: Use these tools on their own code base
Sven Fuchs - Anatomy of Ruby i18n
I18n 0.4 is out
generic key-value backend, so you can use e.g. Redis as backend
I18n is about designing software so it can be adopted to various locales
L10n is the process of translating the software
Scope:
- Looking up translations
- Formats of numbers, dates, times, currency
- Timezones
- etc.
I18n only cares about first two
- Interpolation
- Pluralization
- Defaults
- Namespace
Scenarios:
- Single language
- Multiple languages
- Different storage types
- Model/Data translations
- Lots of special requirements
Simplest thing that could possibly work
I18n::Simple backend
Usually enough, but sometimes you want more:
- Cache
- Fallbacks: Fall back to other translation if chosen locale isn't available
- Pluralizations: Simple algorithm in western languages, but e.g. czech has one, few, and many pluralization forms
- Gettext
- Metadata
Other backends: Chain, ActiveRecord
Advanced features:
- Translation procs
- Interpolation procs
- Translation symlinks
Prefer composition over inheritance
http://gist.github.com/244944 vs. http://gist.github.com/247648
Marcin Kulik - Building web frameworks with Rack
While the world doesn't need another web framework, but it's so easy you should at least try
gain understanding how other web frameworks, rack, HTTP work
Also fun
Existing frameworks all use MVC (more or less)
Let's build our own
Available Rack middleware:
- Use bundler for gem dependency management
- Routing: Usher
- Controller: Should be a full Rack App, use rack-contrib and rack-flash for extras
- Tilt for templates
- DataMapper for ORM
- Warden for authentication
- rack-test for testing
- Console: racksh
CodeRack - Rack Middleware repository
Nicolás Sanguinetti - Continuous Integration and why you need it
CI is a methodology
Integrate frequently, ideally a few times per day
Fix any integration problem ASAP
CI gives instant feedback
CI allows you to deploy anytime with confidence that everything works
Spend less time figuring out what went wrong
Less bugs
Better estimations, since CI means you basically deploy continuously
Just Do It
No software or service required, it's just a practice
Core of CI is commit often, and merge frequently
But automation makes stuff easier
Even a shellscript will do
But no need to reinvent the wheel
Hudson:
- Built with Java
- Easy to set up
- Lots of Plugins
- Multiple SCMs supported
- Multiple Projects
- History of builds
Works, sometimes takes a lot of config
- Simple and tiny
- Single project
- Married to Git
- Easy to hack on
- Easy to set up
- No history
Great, tiny, works like a charm, but limited
- Simple and small
- Multiple projects
- Supports Git out of the box, other SCMs soon
- Easy to hack, set up
- History of builds
Try all of them
Neil Straford and Jason Goecke - Tropo.com - Voice, IM and SMS enable your application
Moho & Tropo replace Asterisk for Adhearsion
Make it easier to scale
Moho: Asynchronous, Multi-Channel, common concepts baked in
Tropo: Cloud Service & Open Source, unified communications API
Simple (only 15 commands)
Synchronous
Speech Recognition & Synthesis
Transcription
Single API for SMS, Twitter, etc.
Tropo Scripting
Each supported language gets a "Shim"
Demo
Play Simon Game: Skype +99000936 9991442790 (Speak in english or enter touch tones)
Lightning Talks
iKey Kung Fu
One Keyboard to rule them all
Each app has its own key combination
No more alt-tab
Instant switch between applications
Single Application mode - all other app windows are hidden
Only limit is number of fingers
MacRuby
RubyCocoa is a bridge between Ruby and Objective-C
Messaging is slow, because it's a bridge
Two object spaces
Green threads vs. native threads
MacRuby: Object => NSObject
Uses LLVM to JIT and AOT
One runtime, object space, shared infrastructure, real threads
Access to Grand Central Dispatch
BareTest
http://github.com/apeiros/baretest
ViewModel
Thin wrapper above models
Meant to replace helper methods which are just there for specific model instances
- song = view_model_for @song
%h1= song.title
Responders are a new feature from Rails 3
Loader
Dynamically reload data without restarting server
Rewriting IRB
IRB is probably oldest ruby program in use
Fragile, hard to change, unmaintainable
DietRB is complete rewrite
Use Ripper to parse Ruby code instead of self-rolled Lexer + Parser
Has completion, history and colorization extensions
Spec descriptions
Already in MacRuby
Needs more eyes to scrutinize
$ gem install dietrb
Agile Project Management with Cucumber FM
(Exactly What It Says On The Tin)
Rails 3 documentation for Mac OS X Dictionary Services
Access Rails 3 docs through Dictionary.app
Simply type keyword
Also works in Spotlight
Also available for Rails 2, Ruby 1.8, jQuery, etc.
Rod, Polish Rails Guides
Rod: Read only data(base)
- Opposite of RDBMS - denormalize data
- Opposite of document database
- written in C
- with Ruby interface, mimicking AR
- why? natural language dictionaries
NoSQL Summer
Worldwide project around NoSQL
Hub
$ brew install hub
$ alias git=hub
Wrapper for Git for easier interaction with GitHub
Open Network graph:
$ git browse -- network
Fetch stuff from forks
$ git fetch mislav,cehoffman
Add a feature
$ git merge mislav/some-feature
Cherry picka URL pasted from browser
$ git cherry-pick http://github.com/defunkt/hub/commit/3a8d7a
Fork:
$ git fork
Copy compare URL to clipboard:
$ git compare -u | pbcopy
DataMapper 1.0.0.rc3
More than an ORM
~210 contributors
~40 (No)SQL adapters and ~120 plugins
Supports many Ruby platforms
One of Zombies
Simple 2D game
Based on Gosu
Strategy game -> kill everything game
Save the innocent -> no end
Template Induction
Useful for screen scraping
Creating templates (e.g. SOAP load generators)
Port from Python version: Templatemaker
Caveat: Really slow
Doesn't actually work
Get to the point already
Don't split methods on the same level of abstraction
ey-integrity
Deploy CI server to Engine Yard cloud
Long polling with Event Machine
(not held due to time constraints)