TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
Ruby for C# Developers
1. Ruby for C# Developers
St. Louis
Code Camp
May 6th, 2006
Cory Foy
http://www.cornetdesign.com
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
2. Overview
• What is Ruby?
• Ruby Basics
• Advanced Ruby
• Ruby and .NET integration
• Wrap-up
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
3. What is Ruby?
• First released in 1995 by Yukihiro
Matsumoto (Matz)
• Object-Oriented
– number = 1.abs #instead of Math.abs(1)
• Dynamically Typed
– result = 1+3
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
4. What is Ruby?
class Person
attr_accessor :name, :age # attributes we can set and retrieve
def initialize(name, age) # constructor method
@name = name # store name and age for later retrieval
@age = age.to_i # (store age as integer)
end
def inspect # This method retrieves saved values
"#@name (#@age)" # in a readable format
end
end
p1 = Person.new('elmo', 4) # elmo is the name, 4 is the age
puts p1.inspect # prints “elmo (4)”
• http://www.rubygarden.org/faq/entry/show/3
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
5. Will It Change Your Life?
• Yes!
• Ok, Maybe
• It’s fun to program with
• And what is programming if it isn’t fun?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
6. Ruby Basics
• Variables, Classes and Methods
• Properties / Attributes
• Exceptions
• Access Control
• Importing Files and Libraries
• Duck Typing
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
7. Ruby Basics - Variables
• Local (lowercase, underscores)
– fred_j = Person.new(“Fred”)
• Instance (@ sign with lowercase)
– @name = name
• Class (@@ with lowercase)
– @@error_email = “testing@test.com”
• Constant (Starts with uppercase)
– MY_PI = 3.14
– class Move
• Global ($ with name)
– $MEANING_OF_LIFE = 42
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
8. Ruby Basics - Classes
class Move
attr_accessor :up, :right
def initialize(up, right)
@up = up
@right = right
end
end
• Class definitions are started with
class,are named with a CamelCase
name, and ended with end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
9. Ruby Basics - Classes
class Move
attr_accessor :up, :right
def initialize(up, right)
@up = up
@right = right
end
end
• Attributes and fields normally go at the
beginning of the class definition
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
10. Ruby Basics - Classes
class Move
attr_accessor :up, :right
def initialize(up, right)
@up = up
@right = right
end
end
• initialize is the same concept as a
constructor from .NET or Java, and is called
when someone invokes your object using
Move.new to set up the object’s state
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
11. Ruby Basics - Methods
class Move
def up
@up
end
def right
return @right
end
end
• Methods return the last expression
evaluated. You can also explicitly return from
methods
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
12. Ruby Basics - Methods
class Move
def initialize(up, right)
@up = up
@right = right
end
end
• Methods can take in specified
parameters, and also parameter lists
(using special notation)
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
13. Ruby Basics - Methods
class Move
def self.create
return Move.new
end
def Move.logger
return @@logger
end
end
• Class (“Static”) methods start with
either self. or Class.
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
14. Ruby Basics - Properties
• Like .NET, Ruby supports the concept
of Properties (called Attributes)
class Move class Move
def up def up=(val)
@up @up = val
end end
end end
move = Move.new
move.up = 15
puts move.up #15
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
15. Ruby Basics - Properties
• Unlike .NET, Ruby provides
convenience methods for doing this
class Move
attr_accessor :up #Same thing as last slide
end
move = Move.new
move.up = 15
puts move.up #15
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
16. Ruby Basics - Properties
• You can specify read or write only
attributes as well
class Move
attr_reader :up #Can’t write
attr_writer :down #Can’t read
end
move = Move.new
move.up = 15 #error
d = move.down #error
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
17. Ruby Basics - Exceptions
• Ruby has an Exception hierarchy
• Exceptions can be caught, raised and
handled
• You can also easily retry a block of
code when you encounter an exception
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
18. Ruby Basics - Exceptions
process_file = File.open(“testfile.csv”)
begin #put exceptional code in begin/end block
#...process file
rescue IOError => io_error
puts “IOException occurred. Retrying.”
retry #starts block over from begin
rescue => other_error
puts “Bad stuff happened: “ + other_error
else #happens if no exceptions occur
puts “No errors in processing. Yippee!”
ensure # similar to finally in .NET/Java
process_file.close unless process_file.nil?
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
19. Ruby Basics – Access Control
• Ruby supports Public, Protected and
Private methods
• Private methods can only be accessed
from the instance of the object, not
from any other object, even those of
the same class as the instance
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
20. Ruby Basics – Access Control
• Access is controlled by using keywords
class Move
private
def calculate_move
end
#Any subsequent methods will be private until..
public
def show_move
end
#Any subsequent methods will now be public
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
21. Ruby Basics – Access Control
• Methods can also be passed as args
class Move
def calculate_move
end
def show_move
end
public :show_move
protected :calculate_move
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
22. Ruby Basics - Imports
• To use a class from another file in your
class, you must tell your source file
where to find the class you want to use
require ‘calculator’
class Move
def calculate_move
return @up * Calculator::MIN_MOVE
end
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
23. Ruby Basics - Imports
• There are two types of imports
– require
• Only loads the file once
– load
• Loads the file every time the method is executed
• Both accept relative and absolute paths, and
will search the current load path for the file
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
24. Ruby Basics – Duck Typing
• What defines an object?
• How can you tell a car is a car?
– By model?
– By name?
• Or, by it’s behavior?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
25. Ruby Basics – Duck Typing
class CarWash
def accept_customer(car)
• How would we
end
validate this
end in .NET or Java?
• We’d use static typing! So only the
valid object could be passed in
• What if my object has the same
behavior as a Car?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
26. Ruby Basics – Duck Typing
• What is
this?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
27. Ruby Basics – Duck Typing
• How
about
this?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
28. Ruby Basics – Duck Typing
• What
about
this?
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
29. Ruby Basics – Duck Typing
• We know objects based on the
behaviors and attributes the object
possesses
• This means if the object passed in can
act like the object we want, that should
be good enough for us!
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
30. Ruby Basics – Duck Typing
Class CarWash
def accept_customer(car)
if car.respond_to?(:drive_to)
@car = car
wash_car
else
reject_customer
end
end
end
• Or we could just let it fail as a runtime
error
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
31. Ruby Basics – Unit Tests
• In a static-typed language, how do we
use the compiler?
– Find misspellings
– Find improper usage
– Enforce contracts
– Find missing semicolons
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
32. Ruby Basics – Unit Tests
• What is a Unit Test?
• “In computer programming, a unit test
is a procedure used to validate that a
particular module of source code is
working properly.” (Wikipedia)
• Sounds like our compiler is just a unit
testing mechanism!
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
33. Ruby Basics – Unit Tests
• Ruby comes built in with a Unit Testing
framework – Test::Unit
– Create individual tests
– Create test suites
– Invoke our tests and suites
• Using this framework and Test-Driven
Development, we can have a high
confidence level in our code
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
34. Ruby Basics – Unit Tests
• Let’s build a toaster!
• Should be able to have
toasting levels set
• Should heat the bread based on
the toasting levels
• Different breads have different
cooking times.
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
35. Ruby Basics – Unit Tests
• Let’s start with a basic test
class TestToaster < Test::Unit::TestCase
def test_toast_bread
toaster = Toaster.new
bread = WonderBread.new
toaster.heat_level = 5
toaster.toast(bread)
assert_equal(“Nicely toasted”, bread.status)
end
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
36. Ruby Basics – Unit Tests
• And run it
root@dilbert $ruby testtoaster.rb
Loaded suite testtoaster
Started
E
Finished in 0.0 seconds.
1) Error:
test_toast_bread(TestToaster):
NameError: uninitialized constant TestToaster::Toaster
testtoaster.rb:4:in `test_toast_bread'
1 tests, 0 assertions, 0 failures, 1 errors
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
37. Ruby Basics – Unit Tests
• Next, let’s build our objects to allow our
test to run
class Toaster class WonderBread
attr_accessor :heat_level attr_accessor :status
end
def toast(bread)
end
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
38. Ruby Basics – Unit Tests
• And run them
root@dilbert $ruby testtoaster.rb
Loaded suite testtoaster
Started
F
Finished in 0.093 seconds.
1) Failure:
test_toast_bread(TestToaster) [testtoaster.rb:10]:
<"Nicely toasted"> expected but was
<nil>.
1 tests, 1 assertions, 1 failures, 0 errors
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
39. Ruby Basics – Unit Tests
• Finally, let’s make the test pass
class Toaster
def toast(bread)
bread.status = “Nicely toasted”
end
end
root@dilbert $ruby testtoaster.rb
Loaded suite testtoaster
Started
.
Finished in 0.0 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
40. Ruby Basics – Unit Tests
• We then keep writing tests to drive the
behavior of the code we want to write
• A side benefit is we get a suite of
regression tests for our code
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
41. Ruby Basics – Unit Tests
• How did the compiler help us again?
– Find misspellings (Unit Tests)
– Find improper usage (Unit Tests)
– Enforce contracts (Duck Typing)
– Find missing semicolons (No
semicolons! ;))
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
42. Advanced Ruby - Modules
• Blocks and Iterators
• Modules
• Mixins / Inheritance
• Reflection
• Other Goodies
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
43. Advanced Ruby - Blocks
• A block is just a section of code
between a set of delimters – { } or
do..end
{ puts “Ho” }
3.times do
puts “Ho “
end #prints “Ho Ho Ho”
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
45. Advanced Ruby - Blocks
• Methods can act like the using statement from
.NET using blocks
def MyConnection.open(*args)
conn = Connection.open(*args)
if block_given?
yield conn #passes conn to the block
conn.close #closes conn when block finishes
end
return conn
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
46. Advanced Ruby - Iterators
• Iterators in Ruby are simply methods
that can invoke a block of code
• Iterators typically pass one or more
values to the block to be evaluated
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
47. Advanced Ruby - Iterators
def fib_up_to(max)
i1, i2 = 1, 1
while i1 <= max
yield i1
i1, i2 = i2, i1+i2 # parallel assignment
end
end
fib_up_to(100) {|f| print f + “ “}
-> 1 1 2 3 5 8 13 21 34 55 89
• Pickaxe Book, page 50
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
48. Advanced Ruby - Modules
• At their core, Modules are like
namespaces in .NET or Java.
module Kite
def Kite.fly
end
end
module Plane
def Plane.fly
end
end
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
49. Advanced Ruby - Mixins
• Modules can’t have instances – they
aren’t classes
• But Modules can be included in
classes, who inherit all of the instance
method definitions from the module
• This is called a mixin and is how Ruby
does “Multiple Inheritance”
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
50. Advanced Ruby - Mixins
module Print
def print
puts “Company Confidential”
yield
end
end
class Document
include Print
#...
end
doc = Document.new
doc.print { “Fourth Quarter looks great!” }
-> Company Confidential
-> Fourth Quarter looks great!
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
51. Advanced Ruby - Reflection
• How could we call the Length of a
String at runtime in .NET?
String myString = "test";
int len = (int)myString
.GetType()
.InvokeMember("Length",
System.Reflection.BindingFlags.GetProperty,
null, myString, null);
Console.WriteLine("Length: " + len.ToString());
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
52. Advanced Ruby - Reflection
• In Ruby, we can just send the
command to the object
myString = “Test”
puts myString.send(:length) # 4
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
53. Advanced Ruby - Reflection
• We can also do all kinds of fancy stuff
#print out all of the objects in our system
ObjectSpace.each_object(Class) {|c| puts c}
#Get all the methods on an object
“Some String”.methods
#see if an object responds to a certain method
obj.respond_to?(:length)
#see if an object is a type
obj.kind_of?(Numeric)
obj.instance_of?(FixNum)
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
54. Ruby Basics – Other Goodies
• RubyGems – Package Management for
Ruby Libraries
• Rake – A Pure Ruby build tool (can use
XML as well for the build files)
• RDoc – Automatically extracts
documentation from your code and
comments
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
55. Ruby and .NET
• Why?
– Provide Scripting ability in your apps
– Quickly prototype
– Class Introspection
• What about JScript.NET?
– Ruby is cross platform
– JScript might be better choice
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
56. Ruby and .NET
• Three projects in the works
• Ruby to .NET Bridge
– http://rubydotnet.sourceforge.net/
• MS Funded Ruby CLR project
– http://www.plas.fit.qut.edu.au/rubynet/
• RubyCLR
– http://rubyforge.org/projects/rubyclr
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
57. Ruby and .NET
• Bridge Example
– Basic Arrays
– Interacting with Objects
– Creating Forms
– Attaching to Events
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com
58. Ruby Resources
• Programming Ruby by Dave Thomas (the
Pickaxe Book)
• http://www.ruby-lang.org
• http://www.rubyforge.org
• http://www.rubycentral.org
• http://www.ruby-doc.org
• http://www.rubygarden.org
• http://www.stlruby.org
St. Louis Code Camp Ruby for C# Developers Cory Foy
May 6th, 2006 http://www.cornetdesign.com