cory foy st. louis code camp may 6th, 2006 ruby for c# developers cory foy st. louis code camp

Post on 18-Jan-2016

223 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

St. Louis Code CampMay 6th, 2006

Ruby for C# Developers Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Cory Foyhttp://www.cornetdesign.com

St. Louis Code Camp

May 6th, 2006

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Overview

• What is Ruby?

• Ruby Basics

• Advanced Ruby

• Ruby and .NET integration

• Wrap-up

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

What is Ruby?

• http://www.rubygarden.org/faq/entry/show/3

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)”

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics

• Variables, Classes and Methods

• Properties / Attributes

• Exceptions

• Access Control

• Importing Files and Libraries

• Duck Typing

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Classes

• Class definitions are started with class,are named with a CamelCase name, and ended with end

class Move attr_accessor :up, :right def initialize(up, right) @up = up @right = right endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Classes

• Attributes and fields normally go at the beginning of the class definition

class Move attr_accessor :up, :right def initialize(up, right) @up = up @right = right endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Classes

• 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

class Move attr_accessor :up, :right def initialize(up, right) @up = up @right = right endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Methods

• Methods return the last expression evaluated. You can also explicitly return from methods

class Move def up @up end

def right return @right endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Methods

• Methods can take in specified parameters, and also parameter lists (using special notation)

class Move def initialize(up, right) @up = up @right = right endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Methods

• Class (“Static”) methods start with either self. or Class.

class Move def self.create return Move.new end

def Move.logger return @@logger endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Properties

• Like .NET, Ruby supports the concept of Properties (called Attributes)

class Move def up @up endend

class Move def up=(val) @up = val endend

move = Move.newmove.up = 15puts move.up #15

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Properties

• Unlike .NET, Ruby provides convenience methods for doing this

class Move attr_accessor :up #Same thing as last slideend

move = Move.newmove.up = 15puts move.up #15

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 readend

move = Move.newmove.up = 15 #errord = move.down #error

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics - Exceptionsprocess_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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Access Control

• Access is controlled by using keywordsclass Move private def calculate_move end #Any subsequent methods will be private until.. public def show_move end #Any subsequent methods will now be publicend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Access Control

• Methods can also be passed as argsclass Move def calculate_move end

def show_move end

public :show_move protected :calculate_moveend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 userequire ‘calculator’class Move def calculate_move return @up * Calculator::MIN_MOVE endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Duck Typing

• 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?

class CarWash def accept_customer(car)

endend

• How would we validate this in .NET or Java?

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Duck Typing

• What is this?

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Duck Typing

• How about this?

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Duck Typing

• What about this?

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Duck Typing

• Or we could just let it fail as a runtime error

Class CarWash def accept_customer(car) if car.respond_to?(:drive_to)

@car = carwash_car

elsereject_customer

end endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Unit Tests

• Let’s start with a basic testclass 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) endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Unit Tests

• And run itroot@dilbert $ruby testtoaster.rbLoaded suite testtoasterStartedEFinished 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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Unit Tests• Next, let’s build our objects to allow our

test to runclass Toaster attr_accessor :heat_level def toast(bread) endend

class WonderBread attr_accessor :statusend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Unit Tests

• And run themroot@dilbert $ruby testtoaster.rbLoaded suite testtoasterStartedFFinished 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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby Basics – Unit Tests

• Finally, let’s make the test passclass Toaster def toast(bread) bread.status = “Nicely toasted” endend

root@dilbert $ruby testtoaster.rbLoaded suite testtoasterStarted.Finished in 0.0 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Modules

• Blocks and Iterators

• Modules

• Mixins / Inheritance

• Reflection

• Other Goodies

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Blocks• Blocks can be associated with method invocations.

The methods call the block using yield

def format_print puts “Confidential. Do Not Disseminate.” yield puts “© SomeCorp, 2006”end

format_print { puts “My name is Earl!” } -> Confidential. Do Not Disseminate. -> My name is Earl! -> © SomeCorp, 2006

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 connend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Iteratorsdef fib_up_to(max) i1, i2 = 1, 1 while i1 <= max yield i1 i1, i2 = i2, i1+i2 # parallel assignment endend

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Modules• At their core, Modules are like

namespaces in .NET or Java.module Kite def Kite.fly endend

module Plane def Plane.fly endend

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Mixinsmodule Print def print puts “Company Confidential” yield endend

class Document include Print #...end

doc = Document.newdoc.print { “Fourth Quarter looks great!” } -> Company Confidential -> Fourth Quarter looks great!

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Reflection

• In Ruby, we can just send the command to the object

myString = “Test”puts myString.send(:length) # 4

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Advanced Ruby - Reflection

• We can also do all kinds of fancy stuff#print out all of the objects in our systemObjectSpace.each_object(Class) {|c| puts c}

#Get all the methods on an object“Some String”.methods

#see if an object responds to a certain methodobj.respond_to?(:length)

#see if an object is a typeobj.kind_of?(Numeric)obj.instance_of?(FixNum)

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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 CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

Ruby and .NET

• Bridge Example– Basic Arrays– Interacting with Objects– Creating Forms– Attaching to Events

St. Louis Code CampMay 6th, 2006

Cory Foyhttp://www.cornetdesign.com

Ruby for C# Developers

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

top related