• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ruby for Perl Programmers
 

Ruby for Perl Programmers

on

  • 11,650 views

Ruby for Perl Programmers

Ruby for Perl Programmers

Statistics

Views

Total Views
11,650
Views on SlideShare
11,380
Embed Views
270

Actions

Likes
17
Downloads
0
Comments
3

12 Embeds 270

http://lfvsfcp10100.dn.net 120
http://cntt.tv 60
http://www.brijj.com 35
http://www.slideshare.net 23
http://www.secguru.com 14
http://twitc.com 6
http://vioan.blogspot.com 3
http://osexp2000.appspot.com 3
http://vioan.blogspot.de 3
http://okniuys.blogspot.com 1
http://209.85.175.104 1
http://www.cntt.tv 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

13 of 3 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Perl isn't interpreted - it's compiled. Sure, a Perl program is compiled every time you run it, so it can look a bit like it's being interpreted - but that's not what is happening.
    Are you sure you want to
    Your message goes here
    Processing…
  • This talk seems like a good idea, but needs some editing. I don't know in what way you could say that Perl has a 'minimalist philosophy' or that it doesn't have 'true closures.' To say that Ruby has 'better #{} support' makes no sense, since #{} is Ruby syntax. Maybe you mean 'better string interpolation'?
    Are you sure you want to
    Your message goes here
    Processing…
  • So, Ruby is Perl (compiled with threads) + Moose, autobox, Error. :)
    But with worse Windows support.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Ruby for Perl programmers

Ruby for Perl Programmers Ruby for Perl Programmers Presentation Transcript

  • Ruby for Perl programmers for Perl programmers Ruby All material Copyright Hal E. Fulton, 2002. Use freely but acknowledge the source.
  • What is Ruby?
    • A scripting language
    • An object-oriented language
    • A dynamic language
    • A Very High Level Language (VHLL)
    • A human-oriented language
    • An open-source project
  • Ruby is General-Purpose
    • One-liners at the command line
    • “ Quick and dirty” scripts
    • System administration tasks
    • CGI scripts
    • GUI apps
    • Networking and distributed apps
  • A Brief History of Ruby…
    • 1993 Conceived by Yukihiro Matsumoto (“Matz”)
    • 1995 First release (Japan)
    • 1999 Version 1.4 released
    • 2000 Programming Ruby published; comp.lang.ruby created
    • 2001 Version 1.6 released; Ruby in a Nutshell published
    • 2001 The Ruby Way published
    • 2002 The Ruby Developer’s Guide published; Teach Yourself Ruby in 21 Days published
  • Where does Ruby get its ideas?
    • Perl (regular expressions, some syntax)
    • SmallTalk (dynamic features, OOP)
    • CLU (iterators)
    • LISP (dynamic features)
    • C (operators, printf/sprintf, etc.)
    • Others
  • Ruby’s Design Principles
    • Principle of Least Surprise (POLS), aka Law of Least Astonishment (LOLA)
    • Human-oriented design
    • Orthogonality, “naturalness,” consistency
    • Flexibility and dynamism
    • TMTOWTDI – “There’s More Than One Way To Do It”
    • TABWTDI – “There’s A Better Way To Do It”
  • Disclaimer:
    • I am not an
    • expert in Perl.
  • How is Ruby like Perl?
    • Scripting language
    • Interpreted, not compiled
    • Minimalist philosophy
    • Good at text processing
    • Understands regular expressions
    • Powerful and versatile
    • Many features borrowed directly from Perl
  • How is Ruby different from Perl?
    • Radically object-oriented from the start
    • Extremely dynamic
    • Built-in threads (non-native)
    • True closures (?)
    • Exception handling
    • Significant syntax differences
  • Some Specific Similarities…
    • Most operators and precedence
    • Most regular expression features
    • Many special variables: $! $& $+ $` $’ $0-$9 $/ $ $, $. $$ $? $_
    • Flexible quoting of strings
    • Multiple assignment
    • __END__, taint, and other features
  • Some Specific Differences…
    • OOP by design: No bless , tie , tied , untie
    • No scope declarations ( my , local )
    • Prefixes indicate scope, not type
    • True/false testing is different
    • Missing special variables: $| %SIG @_ $# $= $~ $% $: $; $[
    • No autovivification
    • Better #{} support
    • Better support for dynamic features
    • No DESTROY, __PACKAGE__, __DATA__
  • Enough! Let’s see some code.
    • The Obligatory Hello, world! Program:
    • puts “Hello, world!” or print “Hello, world! ”
  • Some Basic Syntax
    • # This is a comment.
    • str1 = “Some string.”
    • str2 = ‘Some other string.’
    • # Multiple assignment:
    • a, b, c = 3, 5, 7
    • # Interpolating values in strings:
    • puts “The sum is #{a+b+c}”
  • Some More Syntax
    • var = 123 # Local variable
    • $var = 234 # Global variable
    • PI = 3.14159 # Constant
    • # Note that variables don’t have types!
    • var = “xyz” # redefined
    • # Note that constants really aren’t.
    • PI = 3.1416 # Gives a warning
  • Loops
    • for index in 1..9 do
    • puts “Iteration #{index}”
    • end
    • 1.upto(9) {|index| puts index }
    • index = 1
    • while index < 9 do
    • puts index
    • index += 1
    • end
    • loop { puts “Infinite loop.” }
  • Conditions
    • if x < 5
    • puts “yes”
    • else
    • puts “no”
    • end
    • unless x < 5
    • puts “no”
    • else
    • puts “yes”
    • end
    • if x < 5 then puts “yes” else puts “no” end
    • unless x < 5 then puts “no” else puts “yes” end
    • y = if x < 5 then 23 else 45 end
    • y = unless x < 5 then 45 else 23 end
    • y = x < 5 ? 23 : 45
  • Loop and condition modifier forms
    • puts “Error!” if x < 5
    • puts “Error!” unless x >= 5
    • do_something while notFinished
    • do_something until finished
  • Syntax Sugar and More
    • for loop calls default iterator each
    • x += y is shorthand for x = x + y
    • Most operators are methods
    • Aliases or synonyms are allowed
    • Flexible quoting and array literals
    • Method suffixes ( ? and ! )
  • OOP in Ruby
    • Everything is an object – no wrappers as in Java
    • Standalone functions are really methods of Object
    • Code can be stored as objects
    • Singletons are permitted
    • Metaclasses
    • Data hiding: public , private , protected
    • Etc. …
  • A Simple Class class Person def initialize(name, number) @name, @phone = name, number end def inspect “ Name=#{@name} Phone=#{@phone}” end end # Note that “new” invokes “initialize” a1 = Person.new(“Bill Gates”, “1-800-666-0666”) a2 = Person.new(“Jenny”, “867-5309”) # p is like print or puts but invokes inspect p a2 # Prints “Name=Jenny Phone=867-5309”
  • Defining attributes # Adding to previous example… class Person attr_reader :name # Defines a “name” method attr_accessor :phone # Defines “phone” and # “phone=“ methods end person1 = a2.name # “Jenny” phone_num = a2.phone # “867-5309” a2.phone = “512 867-5309” # Value replaced… p a2 # Prints “Name=Jenny Phone=512 867-5309”
  • Class-level entities class Foobar @@count = 0 # Class variable def initialize(str) @data = str @@count += 1 end def Foobar.population # Class method @@count end end a = Foobar.new(“lions”) b = Foobar.new(“tigers”) c = Foobar.new(“bears”) puts Foobar.population # Prints 3
  • Inheritance class Student < Person def initialize(name, number, id, major) @name, @phone = name, number @id, @major = id, major end def inspect super + “ID=#@id Major=#@major” end end x = Student.new(“Mike Nicholas”, “555-1234”, “ 000-13-5031”, “physics”) puts “yes” if x.is_a? Student # yes puts “yes” if x.is_a? Person # yes
  • Singleton objects # Assume a “Celebrity” class newsguy = Celebrity.new(“Dan Rather”) popstar = Celebrity.new(“Britney Spears”) superman = Celebrity.new(“Superman”) class << superman def fly puts “Look, I’m flying! Woo-hoo!” end end superman.fly # Look, I’m flying! Woo-hoo! newsguy.fly # Error!
  • Garbage Collection
    • No need for destructors
    • No memory deallocation, etc.
    • Currently “mark and sweep” technique
    • Plans for generational GC
  • Using method_missing class OSwrapper def method_missing(method, *args) system(method.to_s, *args) end end sys = OSwrapper.new sys.date # Sat Apr 13 16:32:00… sys.du “-s”, “/tmp” # 166749 /tmp
  • Modules in Ruby
    • Used as mixins (substitute for multiple inheritance); features are “mixed in” to an existing class
    • Used for interface polymorphism; existing class defines method(s) that will be called by the module methods (and vice versa)
    • Used for namespace management
  • Modules as mixins
    • An example of a “pure” mixin is the special Kernel module
    • Because Kernel is mixed into Object , its methods are universally available (without receivers)
    • In most cases, module methods call methods of the class into which they are mixed (interface polymorphism)
  • Modules for Interface Polymorphism
    • Example is Enumerable , which implements methods such as min , max , find , and select
    • These methods depend on the existence of the default iterator each and a method called <=> (used for comparing).
  • Modules for Namespace Management
    • An example is the Math module
    • It has many useful mathematical functions, but these are basically independent of any class or object
    • Therefore Math is really never mixed into a class
    • A similar example is the Process module
  • Module example 1 class MyCollection include Enumerable # interface polymorphism #… def <=>(other) # Compare self to other somehow… # Return –1, 0, or 1 end def each # Iterate through the collection and do # a yield on each one… end end
  • Module example 2 # Namespace management def sin puts “Pride, gluttony, bad commenting…” end x = Math.sin(theta) # unrelated to “our” sin User = Process.uid # uid of this process
  • Module example 3 # A user-defined module module FlyingThing def fly puts “Look, I’m flying!” end end class Bat < Mammal include FlyingThing # A substitute for MI? #… end x = Bat.new x.is_a? Bat # true x.is_a? Mammal # true x.is_a? FlyingThing # true
  • Programming Paradigms
    • Functional Programming (FP): This is possible in a limited way in Ruby (for Haskell fans, etc.)
    • Aspect-Oriented Programming (AOP): A library (AspectR) exists
    • Design-by-Contract (DBC) as in Eiffel: An add-on library exists
    • Design Patterns: The Singleton , Observer , Delegator , and others are already implemented; new ones are relatively easy to implement
    • Extreme Programming (XP): Ruby’s flexible and dynamic nature makes it a natural for XP practices
  • Cool Features in Ruby
    • Iterators (as in CLU)
    • A rich class set
    • Open classes
    • Exceptions
    • Easy extension in Ruby
    • Operator overloading
    • Reflection or dynamic features
    • Threads
    • The Bignum class
    • Continuations
    • Easy extension in C
  • A Rich Set of Classes
    • Array
    • Exception
    • File
    • Hash
    • IO
    • Proc
    • Range
    • Regexp
    • String
    • Struct
    • And others…
  • A Closer Look at Some Classes…
    • Array instance methods: & * + - << <=> == === [ ] [ ]= | assoc at clear collect collect! compact compact! concat delete delete_at delete_if each each_index empty? eql? fill first flatten flatten! include? index indexes indices join last length map! nitems pack pop push rassoc reject! replace reverse reverse! reverse_each rindex shift size slice slice! sort sort! to_a to_ary to_s uniq uniq! unshift
    • IO class and instance methods foreach new pipe popen readlines select << binmode clone close close_read close_write closed? each each_byte each_line eof eof? fcntl fileno flush getc gets ioctl isatty lineno lineno= pid pos pos= print printf putc puts read readchar readline readlines reopen rewind seek stat sync sync= sysread syswrite tell to_i to_io tty? ungetc write
    • String instance methods % * + << <=> == === =~ [ ] [ ]= ~ capitalize capitalize! center chomp chomp! chop chop! concat count crypt delete delete! downcase downcase! dump each each_byte each_line empty? gsub gsub! hash hex include? index intern length ljust next next! oct replace reverse reverse! rindex rjust scan size slice slice! split squeeze squeeze! strip strip! sub sub! succ succ! sum swapcase swapcase! to_f to_i to_s to_str tr tr! tr_s tr_s! unpack upcase upcase! upto
  • Iterators
    • An iterator is a method that can take a code block as a parameter; control is passed back and forth as though they were coroutines.
    • The “standard” iterator is called each ; this can also be called implicitly through a for statement. Example: list = [1, 2, 3, 4, 5] list.each do {|x| puts x if x > 3 } # Equivalently… for x in list puts x if x > 3 end
    • Many classes have other predefined iterators such as foreach , each_byte , reverse_each , and so on.
  • Iterators That Don’t Iterate
    • Sometimes the term “iterator” is not truly accurate; it may serve to enclose a block of code and isolate its context.The canonical example: f = File.open(“somefile”) # Requires a close # But… File.open(“somefile”) do |f| # Process the file as needed; it will be # closed automatically at end of block end
    • Other examples: mutex.synchronize do # Perform thread-sensitive operation, then # release the mutex end Dir.chdir(“/tmp”) do # Temporarily change current directory end
  • Defining Your Own Iterators
    • class Array # Iterate only over an array’s even- # numbered indices…
    • def every_other if block_given? self.each_with_index do |x,i| yield(x) if i % 2 == 0
    • end
    • else
    • raise “No block specified!”
    • end
    • end
    • arr = [11,23,35,47,59,61,73]
    • arr.every_other {|obj| puts obj }
    • # Prints 11 35 59 73
    • arr2 = []
    • arr.every_other {|obj| arr2 << obj }
    • # arr2 is now [11,35,59,73]
  • Interesting Example #1
    • In this code fragment source.each { |line| process(line) } What is source ? We can’t tell!
    • It could be anything that has an iterator each and returns a line at a time.
    • It could be a string with embedded newlines.
    • It could be a file or other IO object.
    • In a sense, we care less about its real “type” or “class” than we care about the methods it implements.
  • Interesting Example #2
    • The POP3 email library defines a POPMail class that has a method called all (to process the entire contents of the message). This method acts as an iterator if it is used with a block: msg.all {|line| puts line }
    • Otherwise it uses the append operator ( << ) on whatever object was passed to it. Thus the object can be any object that responds to the << message: arr = []
    • str = “”
    • out = $stdout
    • msg.all(arr) # Produce an array of lines
    • msg.all(str) # or a string with embedded newlines
    • msg.all(out) # Write each line to stdout
  • Open Classes
    • This means that predefined classes can be
    • added to or modified at will.
    • Example: class String def rot13 self.tr(“A-Ma-mN-Zn-z”,”N-Zn-zA-Ma-m”) end end text = “Elvis is dead.” secret = text.rot13 # Ryivf vf qrnq.
  • Exceptions
    • Help obviate the need for return codes
    • Help eliminate spaghetti “if” logic
    • Example forms: raise raise “Any error message.” raise ArgumentError raise ArgumentError, “Bad data.” raise ArgumentError.new(“Bad data.”) raise ArgumentError, “Bad data”, caller[0]
  • Catching Exceptions, Part 1
    • begin
    • x = Math.sqrt(y/z)
    • # …
    • rescue ArgumentError puts “Error taking square root.”
    • rescue ZeroDivisionError
    • puts “Tried to divide by zero.”
    • end
  • Catching Exceptions, Part 2: The General Form
    • begin
    • # …
    • rescue SomeExceptionType
    • # Can attempt recovery with “retry”
    • rescue SomeOtherType
    • # Same thing, different exception…
    • else
    • # All other exception types
    • ensure
    • # Code here is ALWAYS executed
    • end
  • Other Forms of rescue
    • Inside a method definition: def mymethod # Code… rescue # Handle any exceptions… end
    • Capturing in a variable begin #… rescue SomeType => exc puts exc.message end
    • As a one-liner (modifier form) x = y/z rescue puts “Division by zero!”
  • Easy Extension (in Ruby)
    • Often we can “play” with new features before adding them to the core language.
    • Matz doesn’t have to change the interpreter.
    • We don’t have to write a C extension.
  • Example: Smalltalk-like inject
    • # A Smalltalk-like “inject” method for arrays
    • class Array
    • def inject(initial)
    • result = initial
    • self.each {|x| result = yield(x, result) }
    • result
    • end
    • end
    • nums = [1,2,3,4]
    • sum = arr.inject(0) {|x,acc| acc+x }
    • prod = arr.inject(1) {|x,acc| acc*x }
    • words = [“red”, “green”, “blue”]
    • list = words.inject(“Words:”) {|x,acc| acc+“ ”+x }
    • # list is now: “Words: red green blue”
  • Example: Invert Array to Form Hash
    • class Array
    • def invert
    • h={}
    • self.each_with_index{|x,i| h[x]=i}
    • h
    • end
    • end
    • a = %w[red green blue]
    • h = a.invert
    • # {“blue”=>2, “green”=>1, “red”=>0}
  • Example: Sorting by an Arbitrary Key
    • # Assume class Person with name, age, and height
    • class Array
    • def sort_by(sym)
    • self.sort {|x,y| x.send(sym) <=> y.send(sym)}
    • end
    • end
    • list = [Person.new(&quot;Hansel&quot;, 35, 69),
    • Person.new(&quot;Gretel&quot;, 32, 64),
    • Person.new(&quot;Ted&quot;, 36, 68),
    • Person.new(&quot;Alice&quot;, 33, 63)]
    • # Sorted lists…
    • s1 = people.sort_by(:name)
    • s2 = people.sort_by(:age)
    • s3 = people.sort_by(:height)
    • # s1 is [Alice 33 63, Gretel 32 64, Hansel 35 69, Ted 36 68]
    • # s2 is [Gretel 32 64, Alice 33 63, Hansel 35 69, Ted 36 68]
    • # s3 is [Alice 33 63, Gretel 32 64, Ted 36 68, Hansel 35 69]
  • Example: Existential Quantifiers module Quantifier def any? self.each { |x| return true if yield x } false end def all? self.each { |x| return false if not yield x } true end end class Array include Quantifier end list = [1, 2, 3, 4, 5] flag1 = list.any? {|x| x > 5 } # false flag2 = list.any? {|x| x >= 5 } # true flag3 = list.all? {|x| x <= 10 } # true flag4 = list.all? {|x| x % 2 == 0 } # false
  • Example: Selective File Deletion
    • def delete_if(dir)
    • Dir.chdir(dir) do
    • Dir.foreach(“.”) do |entry|
    • next if File.directory?(entry) # Skip dirs
    • File.unlink(entry) if yield(entry)
    • end
    • end
    • end
    • # Delete files over 5K in size
    • delete_if(“/tmp”) {|f| File.size(f) > 5000 }
    • # Delete log and tmp files
    • delete_if(“/tmp”) {|f| f =~ /(log|tmp)$/i }
    • # Delete files over 24 hours old
    • delete_if(“/home/bill”) {|f| (Time.now-File.mtime(f))>86400 }
  • Other Possible Examples (of Extending Ruby in Ruby)
    • Autovivification of hashes and arrays
    • One-based arrays
    • Better multidimensional array syntax
    • Hash-like constructs that allow duplicates
    • Design-by-contract features
    • AOP features
    • … and much more
  • Dynamic Features of Ruby
    • Dynamic code evaluation ( eval , instance_eval , class_eval , and module_eval )
    • Queries or reflection (finding a class’s methods and so on)
    • Hooks (modifying “behind the scenes” behavior)
    • Callbacks (finding out when something happens, e.g., when a variable is modified)
  • Operator Overloading
    • Most operators can be redefined
    • Example: # Assume a class Length with feet and inches class Length #… def +(other) f = self.feet + other.feet i = self.inches + other.inches if i > 12 then i -= 12; f += 1 end Length.new(f,i) end end board1 = Length.new(5,10) board2 = Length.new(8,9) total = board1 + board2 p total # 14’ 7”
  • Operator Overloading, ex. 2
    • class File
    • def <<(args) self.print(*args) self # Return the file object!
    • end
    • end
    • f = $stdout
    • f << “The time is “ << Time.now << “ currently. ”
  • The Bignum class
    • A Fixnum will transparently “roll over” into a Bignum – an arbitrary-precision integer
    • Example:
    • a, b, c, d, e, f = 237, 365, 451, 666, 2001, 24601
    • product = a*b*c*d*e*f
    • puts product
    • # Output: 1279062690897238830
    • square = product**2
    • # Output: 1636001367245285523749542918059768900
    • cube = product**3
    • # Output:
    • # 2092548311100316744450709557388954690847073917906387000
  • Threads in Ruby
    • Ruby threads allow platform-independent multithreading of applications
    • As such, they are non-native (not pthreads, for example)
    • They do not take advantage of multiple processors
    • They can be started, stopped, synchronized, and killed by means of a number of predefined methods
    • For more sophisticated synchronization, there are add-on libraries available such as monitor.rb
  • Thread Example 1
    • # Thinking ahead during chess…
    • responses = {} # move-response hash
    • humans_turn = true
    • thinking_ahead = Thread.new(board) do
    • predictMove do |m|
    • responses[m] = myResponse(board,m)
    • Thread.exit if humans_turn == false
    • end
    • end
    • human_move = getHumanMove(board)
    • humans_turn = false # Stop the thread gracefully
    • # Now we can access “responses” which may contain
    • # the move the person just made...
  • Thread Example 2
    • # A simple threaded server…
    • require &quot;socket&quot;
    • PORT = 9999
    • server = TCPServer.new(PORT)
    • while (session = server.accept)
    • Thread.new(session) do |my_session|
    • #…
    • my_session.close
    • end
    • end
  • Continuations
    • Continuations are similar to setjmp and longjmp in C; we can do a
    • non-local jump to another context. Contrived example:
    • def mymethod(cont)
    • puts &quot;Line 2&quot;
    • cont.call # &quot;long jump&quot;
    • puts &quot;Line 3&quot;
    • end
    • callcc do |cc| # a Kernel method
    • puts &quot;Line 1&quot;
    • mymethod(cc)
    • puts &quot;Line 4&quot;
    • end
    • puts “Line 5” # Here's the return point
    • # Output:
    • # Line 1
    • # Line 2
    • # Line 5
  • Extending Ruby in C
    • Every Ruby object is accessed as a VALUE (either an immediate value or a pointer)
    • The only header file needed is ruby.h
    • Various rb_* functions correspond to Ruby operations ( rb_ary_push , rb_define_var , and so on)
    • C datatype wrapping is accomplished with Data_Wrap_Struct , Data_Make_Struct , and Data_Make_Struct
    • Rumor has it, it is much easier to extend Ruby than Perl
  • Ruby’s Weaknesses
    • “ Now, the bad news…”
    • Some external add-ons (libraries, tools, utilities) of the language are immature, incomplete, or missing
    • Many things are still documented only in Japanese
    • There are some “issues” with Windows platforms
    • The Ruby Application Archive (RAA) is not nearly so comprehensive as the CPAN as yet
    • User base is limited and expertise is rare
    • Industry acceptance is limited as yet
    • “ And now, back to our regularly scheduled program…”
  • Libraries and Utilities
    • The “one true repository” is the Ruby Application Archive (RAA) accessible from www.ruby-lang.org ; this includes…
    • HTTP, CGI, XML, and related libraries
    • Network and distributed app libraries
    • Development tools (editors, browsers, simple IDEs, syntax highlighting files, debuggers, etc.)
    • Database apps and interfaces
    • GUI, graphics, sound, multimedia in general
    • MS Windows-related libraries
    • Numerical and scientific libraries
    • Documentation
  • Ruby and MS Windows
    • The WIN32API library gives access to the entire Windows API (should you be so bold)
    • The WIN32OLE library provides a Ruby interface for OLE automation
    • ActiveScriptRuby allows Ruby to interface (for example) with the WSH
    • RubyCOM is like a Ruby-to-COM bridge, allowing Ruby to reference VB objects and vice versa
  • Who’s Into Ruby…
    • Dave Thomas and Andy Hunt (the “Pragmatic Programmers”); authors of The Pragmatic Programmer and Programming Ruby
    • Ron Jeffries and Chet Hendrickson , XP gurus and co-authors of Extreme Programming Installed
    • Dan Sugalski , developer for Parrot (the upcoming Perl/Python/Ruby runtime environment)
    • … and a growing user community on comp.lang.ruby!
  • Web Resources
    • www.ruby-lang.org The master site for all things Ruby-related, including the RAA
    • www.rubycentral.com Dave and Andy’s site; very useful info and links
    • www.rubygarden.org A Ruby wiki and a wealth of information
    • www.rubyhacker.com My personal site, still under development
  • Print Resources
    • Programming Ruby , Dave Thomas and Andy Hunt, Addison-Wesley, 2000.
    • Ruby in a Nutshell , Yukihiro Matsumoto, O’Reilly, 2001.
    • The Ruby Way , Sams Publishing, Hal Fulton, 2001.
    • The Ruby Developer’s Guide , Syngress, Michael Neumann et al., 2002.
    • Teach Yourself Ruby in 21 Days , Sams Publishing, Mark Slagell, 2002.
  • The Ruby Way Table of Contents 1. Ruby in Review 2. Simple Data Tasks 3. Manipulating Structured Data 4. External Data Manipulation 5. OOP and Dynamicity in Ruby 6. Graphical Interfaces for Ruby 7. Ruby Threads 8. Scripting and System Administration 9. Network and Web Programming A. From Perl to Ruby B. From Python to Ruby C. Tools and Utilities D. Resources on the Web (and Elsewhere) E. What’s New in Ruby 1.8 More than 300 sections More than 500 code fragments and full listings More than 10,000 lines of code All significant code fragments available in an archive
  • exit(0) # That’s all, folks!