Outline: What it is - General purpose programming language - Interpreted / scripting language (make use of bytecode internally but doesn't write it to the fs) - Influenced by many different other languages / paradigms (see bits and pieces of other languages all over the place) - heavily influenced by Perl, Smalltalk, Eiffel, and Lisp. - Many different interpreters / FOSS communities around them to deploy ruby code in many place History - Originated from japan in the mid 90's - Yukihiro "Matz" Matsumoto, developed language specification and first (and currently the official) interpreter "Matz's Ruby Interpreter (MRI)" - "wanted a scripting language that was more powerful than Perl, and more object-oriented than Python" - JRuby was originally created by Jan Arne Petersen, in 2001 - Rubinius is an alternative Ruby programming language implementation created by Evan Phoenix in 2006 - follows in the Lisp and Smalltalk traditions, by natively implementing as much of Ruby as possible in Ruby code - MacRuby was developed by Laurent Sansonetti, who began work on it in late 2007, releasing the first public version in March 2008 - 2007, at MIX 2007, Microsoft announced/released IronRuby, version 1.0 was just released on 12 April 2010 - MagLev is the name of an upcoming Ruby virtual machine, - compiles Ruby to bytecode, which is then compiled to native machine code using a just-in-time compiler - Many more... Hello world example ruby puts 'Hello world' ruby -e "puts 'Hello world'" $ irb >> puts "Hello world" Hello world => nil >> Ruby Language Features - Thoroughly object-oriented (everything is an object) with inheritance, mixins and metaclasses - 1.to_s => "1" - "FOOBAR".downcase => "foobar" - [[1, 2, 3], [4,5,6]].flatten => [1,2,3,4,5,6] - Dynamic typing and Duck typing - a = 123 ; a = "123" - a.respond_to?(:foo_method) - def foobar(a, b) a + b end foobar(1,2) foobar([1,2,3], [2,3,4]) - Succinct and flexible syntax that minimizes syntactic noise and serves as a foundation for domain specific languages - def foobar(a,b, opts={}, *the_rest) ... end - foobar 1, 2, :some => 'thing', :another => 'widget', 'other', 'things' - Lexical closures, Iterators and generators, with a unique block syntax - def my_method yield(1,2) end - my_method { |a,b| puts "I was passed #{a} and #{b}" } - my_method do |a,b| ... end - File.open('/path/to/something') { |file| file.read ; file.write } - Literal notation for arrays, hashes, regular expressions and symbols - Embedding code in strings (interpolation) - abc = 10 - %q{sup sup #{abc}} => "sup sup #{abc}" - %Q{sup sup #{abc}} => "sup sup 10" - %r{\s*.+}g => /\s*.+/g - %W{some words in an array} => [some, words, in, an, array] - Default arguments def my_method(first, second = 10) .... my_method(20) - Automatic garbage collection - Exception handling -begin do_something raise ArgumentError, "invalid params of some sort" rescue Exception => e # omit 'e' to not bind exception (better performance) or omit 'Exception' to rescue anything that is raised error_handling_code end -catch(:exit_condition) do throw :exit_condition end - Operator overloading - class Widget attr_accessor :internal_int def initialize @internal_int = 0 end def +(another_widget) @internal_int += another_widget.internal_int end end - class Socket def is_open? ... end def halt ... end def halt! ... end end - Custom dispatch behavior (through method_missing and const_missing) class Thing def method_missing(name, *args) puts "You called method #{name} with args #{args.inspect} which doesn't exist" end end Thing.new.foobar "a", "b", "c" - Native threads and cooperative fibers th = Thread.new(p1, p2) { |param1, param2| ... } th.join - Mixins - a class thats mixed with a module - no multiple inheritance in Ruby - can mixin as many modules into a class as you need though - module Covertable def convert ... end end class MyClass include Convertable end MyClass.new.convert - module Enumerable - Native plug-in API in C - extconf.rb - tell ruby how to generate a makefile to compile your extension require 'mkmf' dir_config("hello") create_makefile("hello") - hello.c #include "ruby.h" static VALUE rb_mHello; static VALUE rb_cHelloWorld; void Init_hello() { rb_mHello = rb_define_module("Hello"); rb_cHelloWorld = rb_define_class_under(rb_mHello, "World", rb_cObject); /* nothing here yet */ } - Interactive Ruby Shell (a REPL), demo (come up w/ some commands: list files, some regex manip, web requests, socket stuff, etc....) - cd ... - irb >> Dir.glob("*") >> Dir.pwd >> File.open('foo', 'w') {|f| f.write('bar') } - cat foo >> "foobar" =~ /ob/ >> "foobar"[/b.*/] >> require 'rubygems' >> require 'rest_client' >> res = RestClient.get "http://google.com" >> res.body >> require 'socket' th = Thread.new { server = TCPServer.open(2000) # Socket to listen on port 2000 loop { # Servers run forever client = server.accept # Wait for a client to connect client.puts(Time.now.ctime) # Send the time to the client client.puts "Closing the connection. Bye!" client.close # Disconnect from the client } } s = TCPSocket.open('localhost', 2000) while line = s.gets # Read lines from the socket puts line.chop # And print with platform line terminator end s.close # Close the socket when done - Centralized package management through RubyGems - Implemented on all major platforms - Large standard library Comparison to Other Languages - http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ - Broadly similar to Perl and Python - Unlike Perl, variables are not obligatorily prefixed with a sigil - The language syntax is sensitive to the capitalization of identifiers, in most cases treating capitalized variables as constants. $ represents global variables @ represents objects members @@ represent class members CAPITALS represent constants - Unlike C and Perl, keywords are typically used to define logical code blocks without braces (i.e., pair of { and }) class MyClass def my_method end end f = File.open '/path/to/file' - Line breaks are significant and taken as the end of a statement; a semicolon may be equivalently used a = 1 ; b = 2 a, b = 1, 2 - Unlike Python, indentation/whitespace is not significant - Builtin 'self' reference to class (akin to 'this' in c++), no need to pass into every method like Python - very powerful regex support, akin to what you can do w/ perl, etc - Ruby keeps all of its instance variables completely private to the class and only exposes them through accessor methods (w/ instance_variable_[get|set] exception) - Boolean evaluation of non-boolean data is strict: - 0, "" and [] are all evaluated to true; only nil and false evaluate to false (similar to smalltalk) - Syntatic sugar - "until" & "unless" - Able to put conditional _after_ the statement (do_something if this_is_true ; do_something unless this_is_true ; i += 1 until i > 10) - Multiple return values are allowed (in reality they are just stuffed into an array) def my_method return a,b,c end x,y,z = my_method ra = my_method *ra => a,b,c - Uses message passing for all method calls, similar to smalltalk - Performance vs scalability vs readability / maintainability vs flexability vs dev time Drawbacks (alot are great features that can be misused) - Performance (interpreted) - Dynamic types - Encapsulation can be violated - Classes / modules are always open, even the primitive / basic ones - Metaprogramming can make debugging difficult - Brackets not being required can confuse the parser Widget.new widget_param1, Socket.new socket_param1, widget_or_socket_param? - Unstable API Caveats Ruby != Rails 1.8 vs 1.9 meant to be easy for humans which isn't so easy for the machine Major Frameworks / Projects - Rails - implements mvc design pattern - consists of various subcomponents (activerecord, actionpack, activesupport, activeresource, actionmailer, etc) - powerful framework which will take care of most webapp's needs, plugable architecture - Sinatra - lightweight web framework, focusing on providing a powerful routing api, developer can pull in anything else they need - Puppet - provides a powerful framework to simplify the majority of the technical tasks that sysadmins need to perform - instead of writing a ton of unweildy bash scripts for multi-system admin, an admin can use the simple / concise powerful puppet syntax to setup automated tasks - Rake - the standard ruby build system, similar goals as w/ to make but w/ the power and flexability of Ruby - Webrick / Mongrel / thin - powerful / fast web servers implemented in ruby - Bindings for most major libraries written in c/c++