1. Trang chủ
  2. » Công Nghệ Thông Tin

Rails for Java Developers phần 2 pdf

30 365 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Rails for Java Developers phần 2 pdf
Trường học Unknown University
Chuyên ngành Computer Science
Thể loại Giáo trình
Định dạng
Số trang 30
Dung lượng 192,26 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

It gives you an interactive Ruby shell with Rails and your application’s environment already loaded.. If you go to that file in the sample code, you will find the code is followed imme-d

Trang 1

RUNNING THESAMPLES 31

It is possible to type longer blocks, such as this three-lineif endblock:

If you make as many typing mistakes as we do, you can also paste

multiple lines of code intoirb When code starts to be long enough that

it is unwieldy to enter into irb, you will want to switch to full Ruby

programs

Running Ruby Samples

All the Ruby samples for the book are from the rails_xt/samples

direc-tory, unless otherwise noted in the text So, if you see the following

command:

$ ruby foo.rb

you can execute the same command within therails_xt/samplesdirectory

after you unzip the sample code

Running Rails Samples

The samples include a Rails application in therails_xtdirectory All Rails

commands should be run from this directory, unless otherwise noted

When you see a command that begins withscript, such asscript/console

orscript/server, run that command from therails_xtdirectory

The script/console command is particularly important It gives you an

interactive Ruby shell with Rails and your application’s environment

already loaded Try running script/console from the rails_xt directory in

the sample code

$ script/console

Loading development environment.

>> puts "Hello"

Hello

This is just likeirb, except you can also now call Rails API methods For

example, you could ask what database Rails is using:

>> ActiveRecord::Base.connection.current_database

=> "rails4java_development"

The default prompt inscript/consoleis>> When you see this prompt in

the book, you should be able to run the same code usingscript/console

in therails_xtdirectory

Trang 2

RAILSENVIRONMENTS 32

Running the Unit Tests

We wrote much of the code in this book as exploration tests Exploration exploration teststests are unit tests written for the purpose of learning, teaching, and

exploring Sample code should be tested for the same reason people

unit test anything else: It is easy for us (and you!) to quickly verify that

the code works correctly

You don’t need to run the unit tests to follow along in the book (except

in the testing chapter!), and we typically do not clutter the prose by

including them For example, here is the code from Section 4.8,

Pre-venting the N+1 Problem, on page130, demonstrating a solution to the

N+1 problem in Hibernate:

Download code/hibernate_examples/src/TransactionTest.java

Criteria c = sess.createCriteria(Person class )

.setFetchMode( "quips" , FetchMode.JOIN);

That’s the code you will see in the book, which demonstrates the point

being made Notice that the listing begins with the filename If you go

to that file in the sample code, you will find the code is followed

imme-diately by assertions that prove the code works as intended:

assertEquals(2, people.size());

sess.close();

Person p = (Person) iterator.next();

assertEquals(25, p.getQuips().size());

}

For more about exploration testing, also known as learning tests, see learning tests

“How I Learned Ruby”11 and “Test Driven Learning.”12

Web applications run in three distinct environments:

• In a development environment, there is a developer present Code

and even data schemas tend to change rapidly and interactively

Data is often crufted up by the developer, such as John Smith at

Foo Street

11 http://www.clarkware.com/cgi/blosxom/2005/03/18#RLT1

12 http://weblogs.java.net/blog/davidrupp/archive/2005/03/test_driven_lea.html

Trang 3

RAILSENVIRONMENTS 33

• In a test environment, automated tests run against prepackaged

sample data A developer may or may not be present Data

sche-mas are regularly trashed and rebuilt to guarantee a consistent

starting state for the tests

• In a production environment, code and schemas change much

more rarely The database data is real and valuable, and

develop-ers are rarely present

In Java web frameworks, environments have historically been ad hoc:

Each team evolves its own, using a collection of scripts and Ant tasks

to manage environments and move code and data between them

In Rails, environments are a first-class concept Each application starts

life with the three environments in place Rails environments are used

to select databases, log file destinations, policies for loading code, and

more Here are some of Rails’ environmental defaults:

Development:

• The log file islog/development.log

• The database is{appname}_development

• The breakpoint server is enabled

• Web pages show error stack traces

• Classes reload for each page

Test:

• The log file islog/test.log

• The database is{appname}_test

• The breakpoint server is disabled

• Web pages show generic error messages

• Classes load once at start-up

Production:

• The log file islog/production.log

• The database is{appname}_production

• The breakpoint server is disabled

• Web pages show generic error messages

• Classes load once at start-up

You can change environmental defaults by editing the appropriate

envi-ronment file Envienvi-ronment files are named for the envienvi-ronment they

control, such asconfig/environments/development.rbfor the development

environment (You can even create new environments simply by adding

Trang 4

RAILSENVIRONMENTS 34

files to the config/environments directory.) There is a top-level

environ-ment file namedconfig/environment.rbthat contains settings common to

all environments

It is worth reading through the environment files to get a sense of the

automation that Rails provides Here is a snippet:

The most noticeable aspect is that the configuration is just Ruby In a

Java web application, code is one language (Java), and configuration

is in another (XML) In Rails applications, Ruby is often used for both

code and configuration.13

Let’s try modifying the Rails environment Although Rails’ knowledge of

English grammar is pretty good, you might decide it is not good enough

To experiment with Rails, you can run script/console from any Rails

project, such as the People application at code/people in the sample

The Rails environment includes a pluralization rule smart enough for

emphasis but not for focus We can add our own pluralization rules to

the environment We’ll editconfig/environment.rb (that way our rule will

be available in all environments):

Download code/people/config/environment.rb

inflect.irregular 'focus' , 'foci'

end

13 Other parts of Rails configuration use YAML (YAML Ain’t Markup Language), which is

intended to be easier to read than XML We cover YAML in Section 9.3 , YAML and XML

Compared, on page 261

Trang 5

HOWRAILSCONNECTS TODATABASES 35

Now you should be able topluralize( ) your focus:

$ script/console

Loading development environment.

>> "focus".pluralize

=> "foci"

Rails support scripts and Rake tasks automatically select the

envi-ronment most likely to be right For example, script/console defaults

to development, and rake test defaults to test Many scripts report the

environment they are working in so you don’t forget:

$ script/console

Loading development environment.

It is easy to override the environment for a command Simply prepend

RAILS_ENV=envname For example, you might need to open a console

against a production server to troubleshoot a problem there:

Loading production environment.

Rails programs access relational data through the ActiveRecord library

(see Chapter4, Accessing Data with ActiveRecord, on page96)

Under-neath ActiveRecord, there is a driver layer You will rarely call down into

the driver layer yourself, but you may need to configure the driver for

your application

The database driver configuration is in the fileconfig/database.yml This

file is in YAML format.14 The top-level names indatabase.ymlare Rails

environments—by default, they are the three environments discussed

in Section 1.7, Rails Environments, on page 32 Each top-level name

introduces a collection of indented, name/value pairs to configure the

driver for a particular environment

Rails chooses database names based on your application name plus

the environment name For an application named Whizbang, the initial

config/database.ymlwould look like this:

development:

adapter: mysql

database: whizbang_development

# more driver settings

14 See Section 9.3 , YAML and XML Compared, on page 261 for more about YAML.

Trang 6

RAILSSUPPOR TSCRIPTS 36

# more driver settings Don’t put anything too

important in the test database, since Rails blows this database away as part of running unit and functional tests.

You can override the database names as you see fit by editing the

con-figuration file One common override is to strip the_productionpart from

the production database name

In this book, we are connecting to MySQL as the root user with no

password, because that is the exact setting that a new Rails application

generates by default

Every new Rails application includes a script directory, with a set of

supporting Ruby scripts script is similar to the bin directory in many

Java projects These scripts are run from the top directory of a Rails

project, like this:

stuthulhu:~/myproj stuart$ script/server

Do not navigate into thescriptdirectory and run scripts from there

Rel-ative paths in Rails are always considered from the top project

direc-tory, available within Rails asRAILS_ROOT

You have already seen several scripts in this chapter: script/console,

script/server, andscript/generate All the scripts are summarized here:

script/about

Describes the Rails environment: Rails library versions,

RAILS_ROOT, andRAILS_ENV

script/breakpointer

Is an interactive Ruby shell that will take control of a Rails

appli-cation when abreakpointstatement is encountered

Trang 7

RAILSSUPPOR TSCRIPTS 37

Launches the web server and Rails application

You now know the basic structure of a Rails application, plus some of

the tools you can use to manage the development process You will not

use all this information at once, though Instead, use this chapter as a

road map as you move through the book

In the next chapter, we will take you on an extended tour of Ruby Take

the time now to learn a bit of Ruby, and the rest of the book will be a

snap

Trang 8

Chapter 2

Programming Ruby

Ruby syntax looks pretty foreign to a Java programmer The mission

of this chapter is to explain Ruby syntax and the underlying conceptsthis syntax supports You will be happy to find that many of the under-lying concepts are shared with Java: Ruby’s strings, objects, classes,identity, exceptions, and access specifiers are easily mapped to theircorresponding numbers in the Java world

Java divides the world into primitive types and objects The primitivetypes represent numeric values of various ranges and precision (some-times interpreted in non-numeric ways, for example as text characters

or true/false) Objects represent anything they want to and are posed of behaviors (methods) and state (other objects and/or primi-tives) This section introduces the primitive types and their Ruby coun-terparts

com-Consider the Java primitive typeint:

Download code/java_xt/src/TestPrimitives.java

assertEquals(2, 1+1);

//Zoinks Not four billion!

assertEquals(-294967296 , TWO_BILLION + TWO_BILLION);

}

Trang 9

PRIMITIVETYPES 39

Three factors are immediately evident in this simple example:

• Java variables are statically typed On line 2, the keywordint

indi-cates that TWO_BILLION must be an int The compiler will enforce

this

• Java takes advantage of a syntax we all know: infix math To

eval-uate one plus one, you can say the obvious 1+1 (line 3), rather

than something annoying such as 1.plus(1)

• On line 5, two billion plus two billion does not equal four billion

This is because Java’s primitives are confined to a specific number

of bits in memory, and four billion would need too many bits

To represent arbitrarily large integers, Java uses theBigIntegerclass:

Download code/java_xt/src/TestPrimitives.java

public void testBigInteger() {

BigInteger twobil = new BigInteger( "2000000000" );

BigInteger doubled = twobil.multiply( new BigInteger( "2" ));

assertEquals( new BigInteger( "4000000000" ), doubled);

}

In this example,BigIntegerdiffers fromintin three ways:

• You cannot create aBigIntegerinstance with literal syntax Instead

ofBigInteger b = 10;, you sayBigInteger b = new BigInteger("10")(line 2)

• You cannot use infix mathematical notation On line 3, you have

to saya.multiply(b)instead ofa*b

• On line 4, two billionmultiplytwo does equal four billion

Ruby also knows how to manipulate integers Like Java, Ruby needs to

do the following:

• Enforce type safety

• Provide a convenient syntax

• Deal smoothly with the human notion of integers (which is infinite)

inside a computer (which is finite)

Ruby takes a radically different approach to achieving these goals:

• Everything in Ruby is an object, and types are usually not declared

in source code So instead of int TWO_BILLION= , you simply say

Trang 10

PRIMITIVETYPES 40

TWO_BILLION= There is no compiler to make sureTWO_BILLION is

really an integer

• Ruby allows infix math syntax (2+2) for integers and any other

types that want it

• Two billion plus two billion does equal four billion, as expected

Behind the scenes, Ruby deals with integers of unusual size by

manag-ing two different types:Fixnumfor small integers that have a convenient

representation andBignumfor larger numbers It is possible to find out

which type is actually being used:

irb(main):016:0> 1.class

=> Fixnum

irb(main):017:0> TWO_BILLION.class

=> Bignum

Most of the time you will not care, because Ruby transparently uses

the appropriate type as needed:

Notice thatxsmoothly shifts fromFixnumtoBignumas necessary

We could repeat the previous comparison for the other Java primitives,

but this would be a waste of space, because the underlying story would

be mostly the same as forint Here are a few other factors to remember

when dealing with numeric types in Ruby:

• Numeric types are always objects in Ruby, even when they have a

literal representation The equivalents for methods such as Java’s

Float.isInfinite are instance methods on the numerics For example:

irb(main):018:0> 1.0.finite?

=> true

irb(main):019:0> (1.0/0.0).finite?

=> false

Note that the question mark at the end of finite? is part of the

method name The trailing question mark has no special meaning

to Ruby, but by convention it is used for methods that return a

boolean

Trang 11

If you try something unreasonable, you will know soon enough

because Ruby will throw an exception:

irb(main):027:0> (1.0/0)

=> Infinity

irb(main):028:0> (1/0)

ZeroDivisionError: divided by 0

For information about character types, see Section2.2, Strings, below

For booleans, see Section2.5, Control Flow, on page51

In Java, strings are commonly represented as double-quoted literals

The implementation of JavaString is a class, with methods, fields, and

constructors

However, because string concatenation is so fundamental to many

pro-gramming tasks,Stringalso has some special abilities The most

impor-tant of these is concatenation with the+sign:

Download code/java_xt/src/DemoStrings.java

String name = "Reader" ;

print( "Hello, " + name);

The Ruby syntax is similar:

irb(main):001:0> name = "Reader"

print(String.format( "Hello, %s" , name.toUpperCase()));

Ruby offers a different approach for formatting, using a literal syntax

called string interpolation Inside a double-quoted string, text between string interpolation

#{and}is evaluated as Ruby code

Trang 12

STRINGS 42

This is similar to${}property expansion in Java’s Ant You could write

the preceding example with string interpolation:

Download code/rails_xt/sample_output/interpolation.irb

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

In both the previous Ruby and Java examples, we escaped the

double-quote character inside the string (\") to avoid terminating the string

This kind of escaping can be confusing to read if you escape a lot of

characters:

irb(main):009:0> puts "\"One\", \"two\", and \"three\" are all strings."

"One", "two", and "three" are all strings.

In Ruby, you can get rid of all these backslash escapes You simply pick

an alternate string delimiter such as{}by prefixing a string with%Q:

Download code/rails_xt/sample_output/quoting.irb

irb(main):011:0> puts %Q{"One", "Two", and "Three" are strings"}

"One", "Two", and "Three" are strings"

In Java, individual characters are represented by single quotes You

can pull individual characters from a string via thecharAtmethod:

Download code/java_xt/src/TestStrings.java

public void testCharAt() {

assertEquals( 'H' , "Hello" charAt(0));

assertEquals( 'o' , "Hello" charAt(4));

}

}

Ruby handles individual characters differently Character literals are

prefixed with a question mark:

irb(main):015:0> ?A

=> 65

irb(main):016:0> ?B

=> 66

Trang 13

STRINGS 43

Ruby also handles extraction differently For example, you could call a

method named slice, but Ruby programmers would typically prefer to

use the[ ]syntax instead:

irb(main):019:0> ?H == "Hello".slice(0)

=> true

irb(main):020:0> ?H == "Hello"[0]

=> true

The really cool part of usingslice/[ ]is that it performs reasonable tasks

with all kinds of arguments You can count from the back of a string

with negative offsets:

IndexError: index 1000 out of string

Although interpolation is useful, you will not want it in all cases To

turn off string interpolation, use a single-quoted string instead of a

The embedded backslashes are legal Ruby too, but there is an easier

way Ruby provides an explicit syntax for multiline strings called a here

A multiline string begins with <<, followed by a string of your choice

That same string appears again at the beginning of a line to terminate

the heredoc:

Trang 14

OBJECTS ANDMETHODS 44

Regular expressions provide a powerful syntax for finding and

modi-fying ranges of characters within Strings For example, here is a Java

method that uses a regular expression to bleep out any four-letter

words that appear in aString:

Download code/java_xt/src/Bowdlerize.java

return input.replaceAll( "\\b\\w{4}\\b" , "(bleep)" );

}

}

Ruby uses a literal syntax for regular expressions, delimiting them with

// As a result, a Ruby programmer might bleep like this:

Download code/rails_xt/sample_output/regexp.irb

irb(main):041:0> 'Are four letter words mean?'.gsub(/\b\w{4}\b/, "(bleep)")

=> "Are (bleep) letter words (bleep)?"

The gsub method replaces all matches of its first argument with its

second argument

Notice that the regular expression itself looks slightly different in the

Ruby and Java versions Where you see a single backslash in the Ruby

version, the Java version has a double backslash The Java regular

expression is built from a Java string, and the paired backslashes

translate to single backslashes after the string is parsed The Ruby

regular expression does not pass through a temporary “string phase,”

so the single backslashes are represented directly

In this section, we will show how to use objects by calling their methods

In Section2.6, Defining Classes, on page57, we will show how to define

your own classes of objects

Trang 15

OBJECTS ANDMETHODS 45

You have already seen some examples of objects and methods in

Sec-tion 2.2, Strings, on page41.Strings are just a kind (class) of object: A

method is code that is defined by an object to manipulate the object,

return a result value, or both To invoke a method on a string, or any

other object, append a dot (.), the name of the method, and

parenthe-ses, as in () For example, to get the lowercased version of a string in

Java, you use the following:

Download code/java_xt/src/DemoMethods.java

print( "HELLO" toLowerCase());

Ruby is similar, except the parentheses are optional:

irb(main):047:0> "HELLO".downcase()

=> "hello"

irb(main):048:0> "HELLO".downcase

=> "hello"

Methods often have arguments: one or more pieces of additional

infor-mation that the object uses For example, Java has aMathobject, with

acosmethod that takes a single argument, the angle in radians:

Download code/java_xt/src/DemoMethods.java

print(Math.cos(0));

In this case, the Ruby version can matchexactly, since Ruby also

pro-vides aMathobject

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 The

following code will fail in Java, since strings do not have acosmethod:

Download code/java_xt/src/DemoMethods.java

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

Ngày đăng: 06/08/2014, 09:20

TỪ KHÓA LIÊN QUAN