rubyforjavaprogrammers 1210167973516759-9
TRANSCRIPT
![Page 1: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/1.jpg)
Ruby for Java ProgrammersRuby for Java Programmers
Mike BowlerPresident, Gargoyle Software Inc.
Mike BowlerPresident, Gargoyle Software Inc.
![Page 2: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/2.jpg)
Why learn another language?
![Page 3: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/3.jpg)
Why Ruby?
![Page 4: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/4.jpg)
Timeline: 1993 to 2000Timeline: 1993 to 2000
Created in 1993 by Yukihiro "Matz" Matsumoto
Ruby was popular in Japan but unknown everywhere else
All documentation was written in Japanese
![Page 5: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/5.jpg)
Timeline: 2000-2004Timeline: 2000-2004
First English language book published in 2000
A lot of interest in the Agile development community but mostly unknown elsewhere
![Page 6: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/6.jpg)
Timeline: 2004-todayTimeline: 2004-today
The Ruby on Rails framework has pushed ruby into the spotlight
This is the “killer app”
![Page 7: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/7.jpg)
What influenced it?What influenced it?
![Page 8: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/8.jpg)
TerminologyTerminology
Early
Late
Static
Dynamic
Strong
Weak
![Page 9: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/9.jpg)
Defining strong/weak typing
Defining strong/weak typing
Strong typing
Objects are of a specific type and will not be converted automatically
Java: “4”/2 results in a compile error
Weak typing
Objects can be converted under the covers at any time
Perl: ‘4’/2 => 2
Ruby is strongly typed
![Page 10: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/10.jpg)
Early/late bindingEarly/late bindingEarly binding (aka static binding)
All method invocations must be defined at compile time
Java: foo.getUser()
Late binding (aka dynamic binding)
The runtime does not check that a given method exists until an attempt to invoke it
Smalltalk: foo user.
Ruby uses late binding
![Page 11: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/11.jpg)
SimilaritiesSimilarities
Like Java, Ruby...
runs on a virtual machine
is garbage collected
is object oriented (although to different degrees)
![Page 12: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/12.jpg)
DifferencesDifferences
Everything is an object
Javastring = String.valueOf(1);
Rubystring = 1.to_s()
Primitive
Object
![Page 13: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/13.jpg)
DifferencesDifferences
Many things that you would expect to be keywords are actually methods
throw new IllegalArgumentException("oops");
raise TypeError.new("oops")
Keywords
Methods
![Page 14: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/14.jpg)
DifferencesDifferencesSome syntax optional unless the result is ambiguous
These statements are equivalent
puts("foo");
puts "foo"Idiomatic (better) style
![Page 15: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/15.jpg)
DifferencesDifferencesClasses are real objects
They’re instances of Class
Class methods can be overridden
![Page 16: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/16.jpg)
class ZebraCage < Cage attr_accessor :capacity @@allCages = Array.new
def initialize maximumZebraCount @capacity = maximumZebraCount @@allCages << self end
private def clean_cage # do some stuff here endend
cage = ZebraCage.new 10puts cage.capacity
![Page 17: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/17.jpg)
Multiline ifMultiline ifif name.nil? do_somethingend
![Page 18: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/18.jpg)
Multiline ifMultiline ifif name.nil? do_somethingend
Notice thequestion mark
![Page 19: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/19.jpg)
With an elseWith an elseif name.nil? do_somethingelse something_elseend
![Page 20: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/20.jpg)
Single line ifSingle line ifif name.nil? do_somethingend
do_something if name.nil?
![Page 21: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/21.jpg)
Both kinds of unlessBoth kinds of unlessif name.nil? do_somethingend
do_something if name.nil?
unless name.nil? do_somethingend
do_something unless name.nil?
![Page 22: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/22.jpg)
Dangerous methodsDangerous methods
name = " foo "
name.strip
name.strip!
Returns a new string.Doesn’t modify name.
Modifies name and returns that.
Dangerous!
![Page 23: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/23.jpg)
PhilosophyPhilosophyJava focuses on building blocks
You can build whatever you want with the pieces
Ruby focuses on solving problems
Things you do frequently should be concise
![Page 24: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/24.jpg)
Initializing arraysInitializing arraysList<String> list = new ArrayList<String>();list.add("foo");list.add("bar");
![Page 25: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/25.jpg)
Same only rubySame only rubyList<String> list = new ArrayList<String>();list.add("foo");list.add("bar");
list = Array.newlist << 'foo'list << 'bar'
![Page 26: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/26.jpg)
[][]List<String> list = new ArrayList<String>();list.add("foo");list.add("bar");
list = Array.newlist << 'foo'list << 'bar'
list = ['foo', 'bar']
![Page 27: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/27.jpg)
%w()%w()List<String> list = new ArrayList<String>();list.add("foo");list.add("bar");
list = Array.newlist << 'foo'list << 'bar'
list = ['foo', 'bar']
list = %w(foo bar)
![Page 28: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/28.jpg)
In fairness to java...In fairness to java...List<String> list = new ArrayList<String>();list.add("foo");list.add("bar");
List<String> list = Arrays.asList("foo", "bar");
list = Array.newlist << 'foo'list << 'bar'
list = ['foo', 'bar']
list = %w(foo bar)
![Page 29: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/29.jpg)
Same idea with hashes
Same idea with hashes
Map<String,String> map = new HashMap<String,String>();map.put("foo", "one");map.put("bar", "two");
map = {'foo' => 'one', 'bar' => 'two'}
![Page 30: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/30.jpg)
Special case for Hash
Special case for Hash
hash = {:a => 5, :b => 3}do_stuff 30, hash
do_stuff 100, :a => 5, :b => 3
![Page 31: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/31.jpg)
Regular ExpressionsRegular Expressions
Pattern pattern = Pattern.compile("^\\s*(.+)\\s*$");Matcher matcher = pattern.matcher(line);if( matcher.matches() ) { doSomething();}
![Page 32: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/32.jpg)
Regular ExpressionsRegular Expressions
Pattern pattern = Pattern.compile("^\\s*(.+)\\s*$");Matcher matcher = pattern.matcher(line);if( matcher.matches() ) { doSomething();}
do_something if line =~ /^\s*(.+)\s*$/
![Page 33: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/33.jpg)
Nil and NullNil and NullJava’s nullJava’s null Ruby’s nilRuby’s nil
Absence of an object An instance of NilClass
if( a != null ) {...} unless a.nil? {...}
null.toString() -> NPE nil.to_s -> “”
null.getUser() ->Exception in thread "main" java.lang.NullPointerException
nil.get_user -> NoMethodError: undefined method ‘get_user’ for nil:NilClass
![Page 34: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/34.jpg)
Implications of late binding
Implications of late binding
Method dispatch is quite different
Ruby makes a distinction between “messages” that are sent to an object and the “methods” that get dispatched
![Page 35: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/35.jpg)
Message != MethodMessage != Method
![Page 36: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/36.jpg)
What if there isn’t a method for the specified
message?
What if there isn’t a method for the specified
message?
![Page 37: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/37.jpg)
method_missing example from ActiveRecord
method_missing example from ActiveRecord
user = Users.find_by_name(name)
user = Users.find(:first, :conditions => [ "name = ?", name])
![Page 38: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/38.jpg)
Creating proxy objects
Creating proxy objects
Mock object for testing
Proxy object to allow distributed objects across machines
Wrapper to record usage of a given object
![Page 39: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/39.jpg)
Implementing a proxyImplementing a proxyclass Proxy def method_missing name, *args, &proc puts name,args endend
![Page 40: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/40.jpg)
Implementing a proxyImplementing a proxyclass Proxy def method_missing name, *args, &proc puts name,args endend
Proxy.new.foo_bar ‘a’Proxy.new.to_s
Dispatches to method_missing
Doesn’t go to method_missing
![Page 41: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/41.jpg)
Overriding to_sOverriding to_sclass Proxy def method_missing name, *args, &proc puts name,args end
def to_s method_missing :to_s, [] endend
![Page 42: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/42.jpg)
=•===•=~•__id__•_send__•class•clone•dclonedisplay•dup•enum_for•eql?•equal?•extend freeze
frozen?•hash•id•inspect•instance_eval instance_of?
instance_variable_defined•instance_variable_getinstance_variable_get•instance_variable_set
instance_variable_set•instance_variables•is_a?kind_of?•method•methods•new•nil?•object_id
private_methods•protected_methods•public_meth
odsremove_instance_variable•respond_to?•send
singleton_method_added•singleton_method_removed
singleton_method_undefined•singleton_methods•taint
tainted?•to_a•to_enum•to_s•to_yamlto_yaml_properties•to_yaml_style•type•untaint
![Page 43: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/43.jpg)
Implementing a proxyImplementing a proxy
class Proxy instance_methods.each do |method| undef_method method unless method =~ /^__/ end
def method_missing name, *args, &proc puts name,args endend
Proxy.new.to_s
![Page 44: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/44.jpg)
Unix was not designed to stop people from doing stupid things, because that would also stop them from doing clever things.
—Doug Gwyn
![Page 45: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/45.jpg)
Cultural differences about type
Cultural differences about type
Java is very focused on the types of objects
Is the object an instance of a specific class?
Or does it implement a specific interface?
Ruby is focused on the behaviour
Does the object respond to a given message?
![Page 46: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/46.jpg)
TypesTypes
public void foo( ArrayList list ) { list.add("foo");}
def foo list list << 'foo'end
What’s the type?
What’s the type?
![Page 47: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/47.jpg)
Duck typingDuck typingdef foo list list << 'foo'end
If list is a String=> ‘foo’
If list is an Array=> [‘foo’]
If list is an IO=> string will be written to stream
![Page 48: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/48.jpg)
Duck typingDuck typing
Duck typing implies that an object is interchangeable with any other object that implements the same interface, regardless of whether the objects have a related inheritance hierarchy. -- Wikipedia
"If it walks like a duck and quacks like a duck, it must be a duck." -- Pragmatic Dave Thomas
![Page 49: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/49.jpg)
How does this change how wethink of types?
How does this change how wethink of types?
![Page 50: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/50.jpg)
Overflow conditionsOverflow conditions
int a = Integer.MAX_VALUE;System.out.println(" a="+a);System.out.println("a+1="+(a+1));
a=2147483647a+1= ??
![Page 51: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/51.jpg)
Overflow conditionsOverflow conditions
int a = Integer.MAX_VALUE;System.out.println(" a="+a);System.out.println("a+1="+(a+1));
a=2147483647a+1=-2147483648
oops
![Page 52: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/52.jpg)
Overflow in ruby?Overflow in ruby?
number = 10001.upto(4) do puts "#{number.class} #{number}" number = number * numberend
Fixnum 1000Fixnum 1000000Bignum 1000000000000Bignum 1000000000000000000000000
![Page 53: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/53.jpg)
ClosuresClosures
A closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables. The explicit use of closures is associated with functional programming and with languages such as ML and Lisp. Constructs such as objects in other languages can also be modeled with closures. -- Wikipedia
![Page 54: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/54.jpg)
ClosuresClosures
A closure is a block of code that you can manipulate and query
In Ruby we call them blocks or Procs
A block is a pure closure
A Proc is a block wrapped as an object
We generally use the terms block and Proc interchangeably
![Page 55: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/55.jpg)
ClosuresClosures
multiplier = 5block = lambda {|number| puts number * multiplier }
A block
An instanceof Proc
lambda() is a method to convertblocks into Procs
![Page 56: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/56.jpg)
ClosuresClosures
multiplier = 5block = lambda {|number| puts number * multiplier }
Parameterto the block
![Page 57: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/57.jpg)
ClosuresClosures
multiplier = 5block = lambda {|number| puts number * multiplier }
Able to access variables from outside the block
![Page 58: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/58.jpg)
Proc’sProc’s
multiplier = 5block = lambda {|number| puts number * multiplier }block.call 2
block.arityprints 10
returns number of parametersthat the block takes. 1 in this case
![Page 59: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/59.jpg)
Blocks as parametersBlocks as
parametersmultiplier = 51.upto(3) {|number| puts number * multiplier }
=> 5=> 10=> 15
Same blockas before
Called once for each timethrough the loop
![Page 60: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/60.jpg)
Alternate syntaxAlternate syntax
multiplier = 51.upto(3) {|number| puts number * multiplier }
1.upto(3) do |number| puts number * multiplierend
Equivalent
![Page 61: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/61.jpg)
Why are closures significant?
Why are closures significant?
Presence of closures in a language completely changes the design of the libraries
Closure based libraries generally result in significantly less code
![Page 62: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/62.jpg)
// Read the lines and split them into columnsList<String[]> lines= new ArrayList<String[]>();BufferedReader reader = null;try { reader = new BufferedReader(new FileReader("people.txt")); String line = reader.readLine(); while( line != null ) { lines.add( line.split("\t") ); }}finally { if( reader != null ) { reader.close(); }}
// then sortCollections.sort(lines, new Comparator<String[]>() { public int compare(String[] one, String[] two) { return one[1].compareTo(two[1]); }});
// then write them back outBufferedWriter writer = null;try { writer = new BufferedWriter( new FileWriter("people.txt") ); for( String[] strings : lines ) { StringBuilder builder = new StringBuilder(); for( int i=0; i<strings.length; i++ ) { if( i != 0 ) { builder.append("\t"); } builder.append(strings[i]); } }}finally { if( writer != null ) { writer.close(); }}
# Load the datalines = Array.newIO.foreach('people.txt') do |line| lines << line.splitend
# Sort and write it back outFile.open('people.txt', 'w') do |file| lines.sort {|a,b| a[1] <=> b[1]}.each do |array| puts array.join("\t") endend
![Page 63: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/63.jpg)
Closure File ExampleClosure File Examplefile = File.new(fileName,'w')begin file.puts ‘some content’rescue file.closeend
![Page 64: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/64.jpg)
Closure File ExampleClosure File Examplefile = File.new(fileName,'w')begin file.puts ‘some content’rescue file.closeend Only one line of
business logic
![Page 65: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/65.jpg)
Closure File ExampleClosure File Examplefile = File.new(fileName,'w')begin file.puts ‘some content’rescue file.closeend
File.open(fileName,'w') do |file| file.puts ‘some content’end
![Page 66: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/66.jpg)
Ruby file IO sampleRuby file IO sample
# Load the datalines = Array.newIO.foreach('people.txt') do |line| lines << line.splitend
# Sort and write it back outFile.open('people.txt', 'w') do |file| lines.sort {|a,b| a[1] <=> b[1]}.each do |array| puts array.join("\t") endend
![Page 67: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/67.jpg)
Closure-like things in Java
Closure-like things in Java
final String name = getName();new Thread( new Runnable() { public void run() { doSomething(name); }}).start();
Only one line ofbusiness logic
![Page 68: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/68.jpg)
Closures for Java?Closures for Java?There are a couple of proposals being debated for Java7
Unclear whether any of them will be accepted
In the past, Sun’s position has been that closures didn’t make sense at this point in Java’s evolution
public static void main(String[] args) { int plus2(int x) { return x+2; } int(int) plus2b = plus2; System.out.println(plus2b(2)); }
![Page 69: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/69.jpg)
Inheriting behaviour from multiple placesInheriting behaviour from multiple places
C++ has multiple inheritance
Java has interfaces
Ruby has mixins
![Page 70: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/70.jpg)
C++ : multiple inheritance
C++ : multiple inheritance
![Page 71: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/71.jpg)
Java : inheritanceJava : inheritance
![Page 72: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/72.jpg)
Ruby : mixinsRuby : mixins
![Page 73: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/73.jpg)
MixinsMixins
Cannot be instantiatedCan be mixed in
![Page 74: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/74.jpg)
EnumerableEnumerable
class Foo include Enumerable
def each &block block.call 1 block.call 2 block.call 3 endend
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
![Page 75: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/75.jpg)
EnumerableEnumerable
class Foo include Enumerable
def each &block block.call 1 block.call 2 block.call 3 endend
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
![Page 76: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/76.jpg)
EnumerableEnumerableRequires that the class implement each()
For max, min and sort the <=> operator is also needed
Adds many methods for modifying, searching, sorting the items
all?, any?, collect, detect, each_cons, each_slice, each_with_index, entries, enum_cons, enum_slice, enum_with_index, find, find_all, grep, include?, inject, map, max, member?, min, partition, reject, select, sort, sort_by, to_a, to_set, zip
![Page 77: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/77.jpg)
Reopening classesReopening classesclass Foo def one puts 'one' endend
![Page 78: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/78.jpg)
Reopening classesReopening classesclass Foo def one puts 'one' endend
class Foo def two puts 'two' endend
Reopening the same class
![Page 79: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/79.jpg)
Reopening classesReopening classesclass Foo def one puts 'one' endend
class Foo def one puts '1' endend
Replacing, notadding a method
![Page 80: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/80.jpg)
Reopening core classesReopening core classesclass String def one puts 'one' endend
We reopened a CORE class
and modified it
![Page 81: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/81.jpg)
MetaprogrammingMetaprogramming
Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually.
-- Wikipedia
![Page 82: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/82.jpg)
What changes can we make at
runtime?
What changes can we make at
runtime?
Anything we can hand code, we can programmatically do
Because of late binding, EVERYTHING happens at runtime
![Page 83: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/83.jpg)
attr_accessorattr_accessor
class Foo attr_accessor :barend
class Foo def bar @bar end def bar=(newBar) @bar = newBar endend
Getter
Setter
![Page 84: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/84.jpg)
class Foo def self.attr_accessor name module_eval <<-DONE def #{name}() @#{name} end def #{name}=(newValue) @#{name} = newValue end DONE end my_attr_accessor :barend
Possible implementation of attr_accessor
Possible implementation of attr_accessor
![Page 85: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/85.jpg)
class Foo def self.attr_accessor name module_eval <<-DONE def #{name}() @#{name} end def #{name}=(newValue) @#{name} = newValue end DONE end my_attr_accessor :barend
Possible implementation of attr_accessor
Possible implementation of attr_accessor
“Here Doc”Evaluates to
String
![Page 86: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/86.jpg)
class Foo def self.attr_accessor name module_eval <<-DONE def #{name}() @#{name} end def #{name}=(newValue) @#{name} = newValue end DONE end my_attr_accessor :barend
Possible implementation of attr_accessor
Possible implementation of attr_accessor
Stringsubstitution
![Page 87: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/87.jpg)
class Foo def self.attr_accessor name module_eval <<-DONE def #{name}() @#{name} end def #{name}=(newValue) @#{name} = newValue end DONE end my_attr_accessor :barend
Possible implementation of attr_accessor
Possible implementation of attr_accessor
Executes the stringin the context of
the class
![Page 88: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/88.jpg)
ResultResult
class Foo def bar @bar end def bar=(newBar) @bar = newBar endend
![Page 89: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/89.jpg)
ActiveRecordActiveRecord
class ListItem < ActiveRecord::Base belongs_to :amazon_item acts_as_taggable acts_as_list :scope => :userend
![Page 90: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/90.jpg)
Date :: onceDate :: once
def once(*ids) # :nodoc: for id in ids module_eval <<-"end;", __FILE__, __LINE__ alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) if defined? @__#{id.to_i}__ @__#{id.to_i}__ elsif ! self.frozen? @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) else __#{id.to_i}__(*args, &block) end end end; endend
![Page 91: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/91.jpg)
ObjectSpaceObjectSpaceObjectSpace.each_object do |o| puts o end
ObjectSpace.each_object(String) do |o| puts o end
![Page 92: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/92.jpg)
ObjectSpaceObjectSpaceObjectSpace.each_object do |o| puts o end
ObjectSpace.each_object(String) do |o| puts o end
All objects
Only Strings
![Page 93: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/93.jpg)
ContinuationsContinuations
A snapshot of the call stack that the application can revert to at some point in the future
![Page 94: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/94.jpg)
Why continuations?Why continuations?
To save the state of the application across reboots of the VM
To save the state of the application across requests to a web server
Seaside (smalltalk) does this today
![Page 95: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/95.jpg)
DownsidesDownsidesOnly supported in one implementation of Ruby
Will be removed from the language in Ruby 2.0
![Page 96: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/96.jpg)
ImplementationsImplementationsRuby 1.8.x - “reference implementation” in C
Ruby 1.9 - Next version of C interpreter
Rubinius - Ruby in Ruby (sort-of)
Cardinal - Ruby on Parrot
Iron Ruby - Ruby on the DLR (Microsoft)
Ruby.NET - Ruby on the CLR
JRuby - Ruby on the JVM (Sun)
![Page 97: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/97.jpg)
ImplementationsImplementationsRuby 1.8.x - “reference implementation” in C
Ruby 1.9 - Next version of C interpreter
Rubinius - Ruby in Ruby (sort-of)
Cardinal - Ruby on Parrot
Iron Ruby - Ruby on the DLR (Microsoft)
Ruby.NET - Ruby on the CLR
JRuby - Ruby on the JVM (Sun)
![Page 98: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/98.jpg)
JRubyJRubyRuns on the Java Virtual Machine (JVM)
Full implementation of the Ruby language
Supported by Sun
Runs many benchmarks faster than the 1.8 reference implementation (written in C)
Able to easily call out to Java code
![Page 99: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/99.jpg)
Ruby on RailsRuby on Rails
Web application framework
Sweet spot - web application talking to a single relational database
Allows very rapid development of web apps
![Page 100: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/100.jpg)
Who’s using rails?Who’s using rails?
Amazon • BBC • Cap Gemini Chicago Tribune • Barclays • BPN • Cisco
CNET Electronic Arts • IBM • John Deere JP Morgan Chase • LA Times • Limewire Linked In • NASA • NBC • New York Times
Oakley • Oracle • Orbitz • Turner Media twitter.com • Siemens • ThoughtWorks
Yahoo!
![Page 101: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/101.jpg)
JRuby on Rails?JRuby on Rails?Yes! You can run a rails application on JRuby in a servlet container
Goldspike is the servlet that dispatches to rails
Tested on WebLogic, WebSphere, GlassFish, Jetty, Tomcat
Warbler is the packaging tool that makes the WAR
Supported on: WebLogic, WebSphere, GlassFish, Jetty, Tomcat
![Page 102: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/102.jpg)
RecapRecap
Learning a new language will make you better with all the languages you know
Ruby has a much more concise syntax which means that it takes much less code to solve the same problems
Ruby is able to run on the JVM which makes it an option for shops with heavy investments in J2EE infrastructure
![Page 103: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/103.jpg)
RecapRecapEverything is an object
The language is extremely malleable
New classes/methods can be created on the fly
Existing classes can be modified at any time
![Page 104: Rubyforjavaprogrammers 1210167973516759-9](https://reader035.vdocuments.us/reader035/viewer/2022062704/555a6651d8b42ae7218b4afb/html5/thumbnails/104.jpg)
Contacting meContacting me
Mike [email protected] (company)www.SphericalImprovement.com (blog)
Interested in learning more about how Ruby and Java can coexist in your company? Just ask me.