- 浏览: 31994 次
- 性别:
- 来自: 北京
最新评论
-
不想长大:
头像好帅啊!!!
测试javaeye -
carlosbdw:
1,#config.active_record.whiny_p ...
安装beast论坛 -
rainchen:
生产环境中也是使用svn checkout出来的?我一直都是用 ...
用SSH远程部署rails工程,不使用Capistrano -
grayblur:
magicgod 写道也可以用rsync来拷贝,适用于很多没有 ...
用SSH远程部署rails工程,不使用Capistrano -
magicgod:
也可以用rsync来拷贝,适用于很多没有svn的虚拟主机。
用SSH远程部署rails工程,不使用Capistrano
书名:《Rails for Java Developers》英文版PDF
所处章节:第二章 Programming Ruby
页数范围:38~71
Java/Ruby语法特性对比:
Java divides the world into primitive types and objects. The primitive
types represent numeric values of various ranges and precision:
primitive types can use infix math, for example:
To represent arbitrarily large integers, Java uses the BigInteger class:
BigInteger cannot use infix mathematical notation you have
to say:
Ruby transparently uses
the appropriate type as needed, Notice that x smoothly shifts from Fixnum to Bignum as necessary:
"?" by convention it is used for methods that return a
boolean
In Java, you can use backslash escapes to represent characters:
Ruby also uses backslash escapes:
with %Q you can get rid of all these backslash escapes:
To turn off string interpolation,use a single-quoted string instead of a double-quoted one:
Java:
Ruby provides an explicit syntax for multiline strings called a here
document, or heredoc.
Java:
Ruby use regular expressions, delimiting them with //:
In Java, objects are type-safe. Objects know what they are capable of, type-safe and you cannot ask them to perform methods they do not have:
Ruby objects are also type-safe:
Type Safety Does Not Ensure Correctness!!!
We want to make two important points from these examples:
• Languages evolve and improve over time. Usually improvement
comes not from thin air but from ideas that have already been
explored elsewhere. Java’s For-Each syntax was inspired by other
languages that have similar features. The programmers who facilitate
this kind of cross-pollination are those who become fluent in
multiple programming languages.
• Languages evolve at many levels. Runtimes can change, language
syntax can change, and libraries can change. In Java, iteration
changes like the addition of For-Each are language changes. Similar
changes in Ruby are library changes, since each et. al. are
method calls. Library changes are easier to make than language
changes. (Many developers write libraries, few developers write
languages, and language evolution tends to be retarded by standards
bodies, backward compatibility, and so on.) Merely pointing
out that Java and Ruby enable different approaches to change is
not a value judgment. However, it may lead to value judgments
in a specific context (which you must provide). What parts of your
system need to change? On what timeline, and under whose direction?
Conversely, what parts need to stay rock-solid stable and be
guaranteed to work in the same fashion across different projects
over time?
That’s it. There is no need to declare instance variables (the Ruby equivalent
of fields) because they come into existence automatically when
they are used.Ruby instance variables are
implicitly private, so this designation is unneeded as well.
Defining Constructors
In Java, Notice that the constructor
arguments share the same names as the private fields: firstName and
lastName. To disambiguate, you explicitly prefix the instance variables
with this.
In Ruby, instance
variables must begin with a @, so there is no danger of a name collision
with method parameters.
To a Java eye, this looks like direct access to the fields first_name and
last_name, but in Ruby these are method calls. Even the punctuation (=)
is part of a method name. To make this clearer, here is a hand-coded
version of the accessors:
Sometimes methods apply to a class as a whole, instead of to any particular
instance of a class. In Java these are called static methods:
In Ruby, these methods are called class methods:
The == operator tests for identity. Strings s1 and s2 are == because they
point to the same object. Strings3 is not== to the others. It contains the
same characters, but it is at a different location in memory.
The equals method tests equality, which Java strings define to mean
“containing the same characters.” Thus, string s3.equals the others.
Ruby also distinguishes between identity and equality. Each unique
object has an object_id. Two objects are identical if they have the same
object_id, and the equal? method tests for this:
Ruby does not have any equivalent for package private but supports
public, protected, and private:
Although access control specifiers set a general rule for how you can
use a class, the general rule may need to bend in some circumstances.
For example, an object serializer may bypass protection modifiers to
access all of an object’s state. In Ruby, you can bypass access control
specifiers with send:
You can invoke
the access control methods more than once for the same symbol. At first
glance this may seem silly—why would a class want to have different
levels of access control at different times? One possibility is temporarily
setting methods public so that unit tests can test them:
This sample uses only techniques we have covered thus far. You can
use cleaner ways to set methods public for the duration of a test. One
approach is to use the extend method, described in Section 3.8, Mixins,
on page 90.
所处章节:第二章 Programming Ruby
页数范围:38~71
Java/Ruby语法特性对比:
Java divides the world into primitive types and objects. The primitive
types represent numeric values of various ranges and precision:
int i;
primitive types can use infix math, for example:
1+1;
To represent arbitrarily large integers, Java uses the BigInteger class:
BigInteger twobil = new BigInteger("2000000000");
BigInteger cannot use infix mathematical notation you have
to say:
a.multiply(b)
Ruby transparently uses
the appropriate type as needed, Notice that x smoothly shifts from Fixnum to Bignum as necessary:
irb(main):004:0> x = 10**9 => 1000000000 irb(main):005:0> x.class => Fixnum irb(main):006:0> x *= 100 => 100000000000 irb(main):007:0> x.class => Bignum irb(main):018:0> 1.0.finite? => true irb(main):019:0> (1.0/0.0).finite? => false
"?" by convention it is used for methods that return a
boolean
print(String.format("Hello, %s", name.toUpperCase()));
irb(main):005:0> "Hello, #{name.upcase}" => "Hello, READER"
In Java, you can use backslash escapes to represent characters:
print(String.format("Hello, \"%s\"\nWelcome to Java", name));
Ruby also uses backslash escapes:
irb(main):008:0> puts "Hello, \"#{name}\"\nWelcome to Ruby" Hello, "Reader" Welcome to Ruby
with %Q you can get rid of all these backslash escapes:
irb(main):011:0> puts %Q{"One", "Two", and "Three" are strings"} "One", "Two", and "Three" are strings"
assertEquals('H', "Hello".charAt(0));
irb(main):015:0> ?A => 65 irb(main):019:0> ?H == "Hello".slice(0) => true irb(main):022:0> ?o == "Hello"[-1] => true irb(main):025:0> "Hello"[1,4] => "ello"
To turn off string interpolation,use a single-quoted string instead of a double-quoted one:
irb(main):028:0> "Hello, #{name.upcase}" => "Hello, READER" irb(main):029:0> 'Hello, #{name.upcase}' => "Hello, \#{name.upcase}"
Java:
print("one\ntwo\nthree");
Ruby provides an explicit syntax for multiline strings called a here
document, or heredoc.
irb(main):035:0> puts <<MY_DELIMITER irb(main):036:0" one irb(main):037:0" two irb(main):038:0" three irb(main):039:0" MY_DELIMITER one two three
Java:
public static String bleep(String input) { return input.replaceAll("\\b\\w{4}\\b", "(bleep)"); }
Ruby use regular expressions, delimiting them with //:
irb(main):041:0> 'Are four letter words mean?'.gsub(/\b\w{4}\b/, "(bleep)") => "Are (bleep) letter words (bleep)?"
print("HELLO".toLowerCase());
irb(main):047:0> "HELLO".downcase() => "hello" irb(main):048:0> "HELLO".downcase => "hello"
print(Math.cos(0));
irb(main):051:0> Math.cos(0) => 1.0 irb(main):051:0> Math.cos 0 => 1.0
In Java, objects are type-safe. Objects know what they are capable of, type-safe and you cannot ask them to perform methods they do not have:
print("hello".cos(0));
Ruby objects are also type-safe:
irb(main):057:0> "hello".cos 0 NoMethodError: undefined method ‘cos' for "hello":String from (irb):57
Type Safety Does Not Ensure Correctness!!!
public class PrintArgs { public static void main(String[] args) { for (int n=0; n<args.length; n++) { System.out.println(args[n]); } } }
ARGV.each {|x| puts x} or ARGV.each do |x| puts x end $ ruby samples/print_args.rb one two three one two three irb(main):009:0> ['C', 'Java', 'Ruby'].each {|lang| puts "#{lang} is fun!"} C is fun! Java is fun! Ruby is fun! => ["C", "Java", "Ruby"] irb(main):002:0> ['C', 'Java', 'Ruby'] == %w{C Java Ruby} => true irb(main):002:0> [1,2] + [3] => [1, 2, 3] irb(main):003:0> [1,2,3] * 2 => [1, 2, 3, 1, 2, 3] irb(main):004:0> [1,2,1] - [2] => [1, 1] irb(main):005:0> [1,2] / 2 NoMethodError: undefined method ‘/' for [1, 2]:Array from (irb):5 irb(main):006:0> skills = ['C', 'Java'] => ["C", "Java"] irb(main):007:0> skills.push 'Ruby' => ["C", "Java", "Ruby"] irb(main):008:0> skills.pop => "Ruby"
import java.util.*; public class PrintEnv { public static void main(String[] args) { Map map = System.getenv(); for (Iterator it = map.entrySet().iterator(); it.hasNext();) { Map.Entry e = (Map.Entry) it.next(); System.out.println(String.format("%s: %s", e.getKey(), e.getValue())); } } }
ENV.each {|k,v| puts "#{k}: #{v}"} irb(main):037:0> dict = {:do => "a deer", :re => "a drop of golden sun"} => {:do=>"a deer", :re=>"a drop of golden sun"} irb(main):013:0> dict.fetch(:do) => "a deer" irb(main):014:0> dict.store(:so, "a needle pulling thread") => "a needle pulling thread" irb(main):015:0> dict[:so] => "a needle pulling thread" irb(main):016:0> dict[:dos] = "a beer" => "a beer"
import java.util.Map; public class ForEach { public static void main(String[] args) { for (String arg: args) { System.out.println(arg); } for (Map.Entry entry: System.getenv().entrySet()) { System.out.println( String.format("%s : %s", entry.getKey(), entry.getValue())); } } }
irb(main):017:0> [1,2,3,4,5].collect {|x| x**2} => [1, 4, 9, 16, 25] irb(main):021:0> [1,2,3,4,5].find_all {|x| x%2==0} => [2, 4]
We want to make two important points from these examples:
• Languages evolve and improve over time. Usually improvement
comes not from thin air but from ideas that have already been
explored elsewhere. Java’s For-Each syntax was inspired by other
languages that have similar features. The programmers who facilitate
this kind of cross-pollination are those who become fluent in
multiple programming languages.
• Languages evolve at many levels. Runtimes can change, language
syntax can change, and libraries can change. In Java, iteration
changes like the addition of For-Each are language changes. Similar
changes in Ruby are library changes, since each et. al. are
method calls. Library changes are easier to make than language
changes. (Many developers write libraries, few developers write
languages, and language evolution tends to be retarded by standards
bodies, backward compatibility, and so on.) Merely pointing
out that Java and Ruby enable different approaches to change is
not a value judgment. However, it may lead to value judgments
in a specific context (which you must provide). What parts of your
system need to change? On what timeline, and under whose direction?
Conversely, what parts need to stay rock-solid stable and be
guaranteed to work in the same fashion across different projects
over time?
if (n > 5) { print("big"); } else { print("little"); }
if n>5 puts "big" else puts "little" end or puts(if (n>5) "big" else "little" end)
if (o != null) { print("got o"); }
o = nil puts o ? true : false if lines > 1; puts "you have more than one line"; end puts "you have more than one line" if lines > 1 puts "you've got lines" if lines != 0 puts "you've got lines" unless lines == 0 The following program runs an input loop, shouting back everything passed via stdin: line = "" puts "Shouting back #{line.upcase}" while line=gets The ugliness here comes from using the boolean operator || to shoehorn two statements into one to conform to the requirements of the statement modifier form. irb(main):026:0> i=1; puts(i*i) || i+=1 while i<=5 1 4 9 16 25 (1..5).each {|x| puts x*x} irb(main):014:0> (1..10).max => 10 irb(main):015:0> (1...10).max => 9 irb(main):016:0> (1..10).exclude_end? => false irb(main):017:0> (1...10).exclude_end? => true ("A".."C").each {|x| puts x*5} AAAAA BBBBB CCCCC irb(main):003:0> ('A'..'I').step(2) {|x| print x} ACEGI
public static int numberGrade(char letter) { switch(letter) { case 'a': return 100; case 'b': return 90; case 'c': return 80; case 'd': return 70; case 'e': case 'f': return 0; } return 0; }
def number_grade(letter) case letter when 'A': 100 when 'B': 90 when 'C': 80 when 'D': 70 else 0 end end def letter_grade(x) case x when 90..100: 'A' when 80..90: 'B' when 70..80: 'C' when 60..70: 'D' when Integer: 'F' when /[A-F]/: x else raise "not a grade: #{x}" end end irb(main):018:0> case('John') irb(main):019:1> when('John'): 'a name' irb(main):020:1> when(String): 'a word' irb(main):021:1> end => "a name" You can also invoke the case equality operator directly; it is written as a triple equals (===): irb(main):002:0> (90..100) === 95 => true irb(main):003:0> (90..100) === 95.5 => true irb(main):004:0> (90..100) === 0 => false irb(main):005:0> Integer === 95 => true irb(main):006:0> Integer === 95.5 => false
public class Person { private String firstName; private String lastName;
class Person
That’s it. There is no need to declare instance variables (the Ruby equivalent
of fields) because they come into existence automatically when
they are used.Ruby instance variables are
implicitly private, so this designation is unneeded as well.
Defining Constructors
In Java, Notice that the constructor
arguments share the same names as the private fields: firstName and
lastName. To disambiguate, you explicitly prefix the instance variables
with this.
public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }
In Ruby, instance
variables must begin with a @, so there is no danger of a name collision
with method parameters.
def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end
public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFullName() { return String.format("%s %s", firstName, lastName); }
attr_accessor :first_name, :last_name def full_name "#{first_name} #{last_name}" end Ruby also provides attr_reader and attr_writer if you want read-only or write-only properties. p.first_name = 'Justin' p.last_name = 'Gehtland' puts "Hello from #{p.first_name}"
To a Java eye, this looks like direct access to the fields first_name and
last_name, but in Ruby these are method calls. Even the punctuation (=)
is part of a method name. To make this clearer, here is a hand-coded
version of the accessors:
# don't do this--use attr_accessor! def first_name @first_name end def first_name=(new_name) @first_name = new_name end
public void marry(Person other) { String newLastName = String.format("%s-%s", getLastName(), other.getLastName()); setLastName(newLastName); other.setLastName(newLastName); }
def marry(other) other.last_name = self.last_name = "#{self.last_name}-#{other.last_name}" end If you forget to prefix a setter with self, you may create hard-to-find bugs. Java does not suffer from this ambiguity, so be careful.
Sometimes methods apply to a class as a whole, instead of to any particular
instance of a class. In Java these are called static methods:
public static String getSpecies() { return "Homo sapiens"; }
In Ruby, these methods are called class methods:
def self.species "Homo sapiens" end
public class Person { private String firstName; private String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFullName() { return String.format("%s %s", firstName, lastName); } public void marry(Person other) { String newLastName = String.format("%s-%s", getLastName(), other.getLastName()); setLastName(newLastName); other.setLastName(newLastName); } public static String getSpecies() { return "Homo sapiens"; } }
class Person def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end attr_accessor :first_name, :last_name def full_name "#{first_name} #{last_name}" end def marry(other) other.last_name = self.last_name = "#{self.last_name}-#{other.last_name}" end def self.species "Homo sapiens" end end
The == operator tests for identity. Strings s1 and s2 are == because they
point to the same object. Strings3 is not== to the others. It contains the
same characters, but it is at a different location in memory.
The equals method tests equality, which Java strings define to mean
“containing the same characters.” Thus, string s3.equals the others.
public void testEquals() { String s1 = "Java rocks!"; String s2 = s1; String s3 = new String("Java rocks!"); assertTrue(s1 == s2); assertFalse(s1 == s3); assertTrue(s1.equals(s3)); }
Ruby also distinguishes between identity and equality. Each unique
object has an object_id. Two objects are identical if they have the same
object_id, and the equal? method tests for this:
irb(main):001:0> s1 = s2 = "Ruby rocks!" => "Ruby rocks!" irb(main):002:0> s1.object_id => 190400 irb(main):003:0> s2.object_id => 190400 irb(main):004:0> s2.equal? s1 => true irb(main):006:0> s3 = "Ruby rocks!" => "Ruby rocks!" irb(main):007:0> s4 = "Ruby rocks!" => "Ruby rocks!" irb(main):008:0> s3==s4 => true irb(main):009:0> s3.eql? s4 => true irb(main):010:0> s3.equal? s4 => false Java’s == tests for identity, while Ruby’s == usually tests for equality
import java.util.*; public class AccessMe { private String name; private List stuff; public AccessMe(String name) { this.name = name; stuff = new ArrayList(); } public String getName() { return name; } protected List getStuff() { return stuff; } private void clear() { name = null; stuff = null; } }
Ruby does not have any equivalent for package private but supports
public, protected, and private:
class AccessMe def initialize(name) @name = name @stuff = [] end attr_accessor :name protected attr_accessor :stuff private def clear @name = @stuff = nil end end
Although access control specifiers set a general rule for how you can
use a class, the general rule may need to bend in some circumstances.
For example, an object serializer may bypass protection modifiers to
access all of an object’s state. In Ruby, you can bypass access control
specifiers with send:
a = AccessMe.new("test") a.send :stuff=, 'some stuff' puts a.send(:stuff)
You can invoke
the access control methods more than once for the same symbol. At first
glance this may seem silly—why would a class want to have different
levels of access control at different times? One possibility is temporarily
setting methods public so that unit tests can test them:
def test_clear AccessMe.send :public, :clear, :stuff a = AccessMe.new("test") a.clear assert_nil a.stuff end
This sample uses only techniques we have covered thus far. You can
use cleaner ways to set methods public for the duration of a test. One
approach is to use the extend method, described in Section 3.8, Mixins,
on page 90.
try { methodThatOpensFile(); } catch (FileNotFoundException fnfe) { System.out.println("File not found " + fnfe); } catch (Exception e) { System.out.println("Caught " + e); }
begin File.read 'nonexistent' rescue SystemCallError => e puts 'system call failed' rescue Exception => e puts 'generic failure of some kind' else puts 'nothing failed' ensure puts 'this always executes' end begin 1/0 rescue Exception => e puts "Message " + e.message puts "Backtrace " + e.backtrace.join("\n") end
相关推荐
《Rails for Java Developers》是一本专为Java开发者撰写的书籍,旨在帮助他们快速掌握Ruby on Rails框架。本书由Stuart Halloway和Justin Etheredge合著,并于2007年2月出版。该书的目标读者是那些对Ruby on Rails...
Ruby on Rails for PHP and Java Developers(2007.8).part1.rar
Ruby on Rails for PHP and Java Developers(2007.8).part4.rar
Ruby on Rails for PHP and Java Developers(2007.8).part3.rar
Ruby on Rails for PHP and Java Developers(2007.8).part2.rar
**标题与描述解析:** 本书《Rails for .NET Developers》旨在为已有.NET开发经验的学习者提供一条快速上手Ruby on Rails(简称RoR)的路径。通过本书,读者不仅能够学习到Ruby语言的基础知识及其面向对象编程的特点...
《Ruby on Rails for Dummies》是一本专门为初学者设计的Ruby on Rails教程,它旨在帮助新手快速理解并掌握这个强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby编程语言构建的一个开源Web应用程序框架,它...
Rails for Zombies是一份面向初学者的教程,通过学习本教程,用户能够掌握创建Ruby on Rails应用程序的基本知识。 Rails for Zombies教程中的"Deep in the CRUD"部分深入讲解了CRUD(创建Create、读取Retrieve、...
Pragmatic.Bookshelf.Rails.for.PHP.Developers
标签 "源码" 暗示了这篇笔记可能会涉及到一些实际的代码示例,读者可以通过阅读源码来理解和学习Rails查询的细节。而 "工具" 可能指的是Rails中用于辅助查询的工具或gem,如ActiveRecord的 scopes 和 relations,...
ruby on rails for eclipse开发插件
通过阅读"Ruby for Rails.pdf"和"Ruby on Rails 初体验.ppt",你可以深入了解Ruby on Rails的各个方面,包括其哲学、核心概念以及如何构建实际的Web应用程序。随着对Rails的理解加深,你将能够高效地开发出功能丰富...
文件名称 "Rails for Java Developers.pdf" 明确指出,这本书是专门为Java开发者设计的,目标是帮助他们过渡到Rails开发。这意味着书的内容可能包括: 1. **Rails基础**:介绍Rails的核心概念,如MVC架构、...
Ruby for Rails 英文原版, pdf格式 <br>本书是一部专门为Rails实践而写的经典Ruby著作,由四部分组成,共17章。第一部分讲述Ruby和Rails的编程环境。第二部分和第三部分与 Rails紧密联系,着重对Ruby这门语言...
### Agile Web Development with Rails for Rails 3.2 #### 核心知识点概览 - **Rails 3.2概述** - **敏捷开发方法论** - **Model-View-Controller (MVC) 模式** - **Ruby on Rails基础与高级特性** - **面向对象...
### Ruby on Rails For Dummies #### 核心知识点解析 **1. Ruby on Rails 概述** - **定义与特点**:Ruby on Rails(简称 Rails 或 RoR)是一种基于 Ruby 语言的开源 Web 应用框架,它采用了 Model-View-...