By Developers, For Developers

Historical errata for Enterprise Integration with Ruby

PDF PgPaper PgTypeDescriptionFixed onComments
169TYPO

“According to Steven’s…” should read “According to Stevens’…”

2005-11-06
149SUGGEST

Notwithstanding the REST and SOAP sections, will there be an asychronous messaging section, beyond RPC? Covering integration with JMS (w/ STOMP?), Microsoft queuing, Tibco, or even native ruby messaging systems, if any exist. Maybe even a discussion of SOA/ESB, as buzzwordy as they are…

(Maik says: Good suggestion, but IMHO Ruby’s support for messaging systems is too weak at the moment.)

2005-11-06
171TYPO

“the required shred libraries” should be “the required shared libraries”

2005-11-06
74OK

Why not “puts doc” instead of “puts doc.target!”?

(Maik says: Omitting target! results in the following error:

test_builder.rb:7:in `puts’: Builder::XmlMarkup#to_ary should return Array (TypeError))

2005-11-06
83SUGGEST

Mutliple text nodes can occur even without mixed content, depending on how the node was built. May want to mention as a possible source for errors.

(Maik says: That’s a really good point and I have added the following paragraph to the according sidebar:

\t Sometimes you do not parse an XML
document yourself, but get it as an
REXML::Document object from
another method. In these cases be prepared to get
elements do not have mixed content, but more than one
text node. Depending on the way the elements were built,
it can easily happen.
\t

)

2005-11-06
65SUGGEST

Second criterion for well-formedness could be more clear: A single top-level element is required, and other elements must be properly nested

2005-11-06
156SUGGEST

I am not seeing that log4r’s corresponding methods are still in place after setting a custom configuration — am I misunderstanding the text?

(Maik says: Stuart is right. I could swear I have tested it. Probably, I have used the info() method that appears in both level hierarchies. I have removed the whole sentence.)

2005-11-06
61SUGGEST

I’d just like to put in my vote for more LDAP info in general, and, if you can, more on ActiveLDAP, which I believe currently has some bugs and is not actively maintained.

If it fits the scope of the book, specific information on relating LDAP entries to ActiveRecord entries (and other Rails/LDAP integration) would be fantastic.

(Maik says: I’ll give it my best)

2005-11-06
TOCSUGGEST

You simply cannot do a book on Enterprise Integration without addressing JMS.

And I would put JMX on my wishlist. Even if you don’t want to make Ruby objects manageable, it would be nice to manage Java objects from within Ruby via JMX.

(Maik says: Currently it seems that no Ruby binding for any of the popular message queue products like MQSeries or SonicMQ does exist (not to speak of a generic JMS binding). I’d highly appreciate, if someone could come up with a solution and I’d be the first to test it and write about it. Until then I suggest to read chapter 5 (coming soon) and use the Ruby Java Bridge to get access to Java classes at least.)

2005-11-08
1SUGGEST

I’ve seen the clause “x looked different to y” in other Prag Prog books. Here, you’ve got “…real world looks completely different to your expectations.”

I believe the correct idiom would be “x differs from y”, as in “…real world looks completely different from your expectations.”

(Dave says: that’s probably my fault—‘to’ seems to be English usage. For example, “different to”, “different than”. “Different from” is the construction that no one will object to. “Different to” is fairly common informally in the U.K., but rare in the U.S. “Different than” is sometimes used to avoid the cumbersome “different from that which”, etc. (e.g., “a very different Pamela than I used to leave all company and pleasure for” — Samuel Richardson). Some U.S. speakers use “different than” exclusively. Some people have insisted on “different from” on the grounds that “from” is required after “to differ”. But Fowler points out that there are many other adjectives that do not conform to the construction of their parent verbs (e.g., “accords with”, but “according to”; “derogates from”, but “derogatory to”).

2006-03-05
1TYPO

Maybe: “some are fairly new and seemingly not two of them were written using the same tools.” Might be understandable, but do you mean “some are fairly new and seemingly no two of them were written using the same tools” instead?

2005-11-08
3TYPO

“does not happen, when” - there should be no comma after “happen,” as it is not an interstital comment in the sentence that follows it

2006-03-05
86TYPO

the parser would invoke xmldecl(‘{}1.0’{}, ‘{}iso-8859-1’{}, nil).

It looks like there are some TEX (or other markup) placeholders left in the code sample here.

2005-11-10
114TYPO

For generating CSV data we use the generate(stream, fs=‘{},’{}, rs=nil, &block) method of class CSV::Writer.

Curly-braces in code text

2005-11-10
115TYPO

Looks like paren operator appears where square-brackets are expected in textual description:

Our newly created class has accessors for all the header columns (id, name, price, description) and new instances can be created using the new( ) or []( )-operator (as shown in line 5).

2005-11-14
165TYPO

In formatted text
Configurator[‘basebath’] = ‘/tmp’
I presume this should say “basepath”

2005-11-10
31SUGGEST

When using libraries that are installed as gems, it is better to not use the require_gem command unless you need a particular version of the library. Just pretend the library is loaded normally and use a regular require.

For example, instead of:

require ‘rubygems’
require_gem ‘activerecord’

use instead:

require ‘rubygems’
require ‘active_record’

(note the underbar in the required file name).

This will work even if active_record is installed directly. The require ‘rubygems’ can be omitted if rubygems in included automatically (as is the case in the windows one-step installer).

2005-11-11
70ERROR

I think the lines in encode_markup() need to be rearranged - the gsub for the amp entity needs to be first, or else a quote, for example, in your markup comes out as a double entity, an amp and then a quot.

2005-11-12
122OK

Neither the parrot example nor the status monitor examples work for me. Win2K Pro, ruby 1.8.2

The server starts but does nothing.

Dave says: the author has tried the parrot server and the status monitor on a Win XP Pro box and they ran without problems. Could you possibly send him more details (via me: dave at pragprog.com)

2005-11-14
0DEFER

JMS is very sorely needed, as another errata mentions. The best way is probably to talk about STOMP and ActiveMQ. It’s a brilliant concept otherwise.

(Maik says:

here’s a list of things I’d put into a second edition:

Databases chapter:

  • Og
  • LDAP and SSL

XML chapter:

  • the new libxml binding
  • create XML documents with XmlSimple

Low Ceremony Distributed Applications chapter:

  • http-access2
  • Mongrel

Distributed Applications with RPC chapter:

  • SOAP and SSL

Messaging (new chapter):

  • ActiveMQ (http://stomp.codehaus.org/Ruby)
  • JMS

Tools and Techniques chapter:

  • domain specific languages
  • Switchtower
  • Puppet (http://reductivelabs.com/projects/puppet)
  • Ruby and .NET

)

7TYPO

Bottom paragraph, last sentence “tools such object-relational” should be “tools such as object-relational”.

2005-11-30
43TYPO

In the code example, at bouquet.base_price = 1.37; the line ends with a semi colon for no reason.

2005-11-30
50TYPO

At the bottom of the next to last paragraph it says “The directory belonging to our init.ldif file looks like (…).” The sentence is not complete and should probably point to some graph.

2005-11-30
76TYPO

The output from the code example for generating CDATA sections seem to have been encoded on time to much, since the less than and greater than signs have been encoded.

2006-01-03
80SUGGEST

The code example on the page uses an XML document with a root element called “text”, and then uses the method “text” on doc.root to get the text data inside of the text element. I suggest that the “text” root element should be renamed to enhance clarity. I had trouble understanding if the method call doc.root.text used the tag name or had the generic name text.

2005-11-30
90ERROR

The code example doesn’t handle the case of more than one text node inside of the consignee element gracefully. Probably the @in_consignee = false expression should be moved to tag_end for the consignee element, and some string concatenation added to the text method.

2006-03-05
111ERROR

The 3 regexps for matching file endings should escape the dot character, as in /\\.dtd$/ otherwise the dot will mean any character.

2005-11-30
119TYPO

Third paragraph, “…first to adapt the distributed…” should probably be either “…first to adapt to the distributed…” or “…first to adopt the distributed…”

2005-11-30
152TYPO

The code for emitting a warning message, and the message that’s shown does not match. One says “I’ve warned you” and the other says “It’s getting boring.”

2005-11-30
154TYPO

Bottom page, last word is “to”, first word on page 155 is also “to”. Probably doubled for some reason.

2005-11-30
31DEFER

Current support for IBM DB2 while claimed for Ruby doesn’t appear to work at all on Windows. There is an appeal to IBM to fix this, but this is currently a real barrier to Ruby in enterprises.

Ruby cannot act as a wholesale replacement for Java in the enterprise, but rather will need to operate alongside of it.
The productivity gains for using Ruby on Rails are much more credible in the enterprise when they can be realized against the existing legacy database schemas.

Along the same line, I also concur with the other postings on the need for integration with JMS.

Also, the mapping of ORM such as ActiveRecord to legacy databases deserves much more detailed information in the book. For instance, there are cases where the ‘legacy’ database schema is in fact one that has been designed for another ORM (using Java) that includes a number of columns such as:

oid (int), created (timestamp), modified (timestamp), etc.

These columns may have been automatically set by the previous ORM so it would make sense to extend ActiveRecord so that it can cleanly assume the same automatic functions for setting the timestamps, etc.

55TYPO

Second paragraph, second line: “nil,so” should be “nil, so”.

2005-11-30
73TYPO

First line after the second XML listing: “That’s how it should look like” should read “That’s how it should look”

2006-01-03
155TYPO

Relics is misspelled

“One of the last relicts is a C server that handles all things related to the creation of greeting cards.”

2005-11-30
159TYPO

It says “Null value (this a an unofficial…”, probably mistyped a.

2005-11-30
172TYPO

After the code for do_PUT at the top of the page, the sentence reads “The code is sort” instead of “The code is short”

2005-11-30
XDEFER

I really enjoy the content of the book. Since this books
deals with ENTERPRISE solutions. I would like to ask if you can spend some time to touch about:
1. Switchtower (http://manuals.rubyonrails.com/read/book/17)
which deals with sofware deployment in general (other than Rails)
2. Puppet (http://reductivelabs.com/projects/puppet)
for system management

I believe the book will become a SUPER Bible with the above
topics which are very important in ENTERPRISE environment.

Thanks,
Hoang Uong

45OK

The transition from the AddLifeTime class to the actual migration code on the following page is somewhat abrupt. It is not clear to someone who is not familiar with migrations exactly what is going on and how to run / use this code.

33SUGGEST

In the code

cheap = Flower.find(:all, :conditions => [‘price < 0.80’])

should probably use the form of :conditions that prevents
SQL injection attacks, just in case somebody reading the
book replaces the 0.80 with #{var}. Something like this:

cheap = Flower.find(:all, :conditions => [‘price < ?’, 0.8])

2006-01-03
30OK

In the “Object-Relational Mappers for Ruby” sideline on
page 30, for people who don’t know that there is a package
or project named ActiveRecord, the box doesn’t distinguish
between the Active Record definition outlined by Martin
Fowler and the project with the same name, as the
ActiveRecord project isn’t introduced until the top of page
31.

38SUGGEST

In introducing the stock_items table, I’m wondering why the
quantity of flowers wasn’t just added as a column to the
flowers table. Clearly, the book needs an example of the
one-to-one relationship, but explaining the decision to do
this would be good.

Maybe the bouquet’s can also be a stock item? When a
bouquet is made, the quantity of flowers used to make
it can be reduced and the stock item for the bouquet
can be incremented.

2006-01-03
39SUGGEST

When creating the flower in

Flower.new(:stock_item_id => si.id, ……)

you could do the more object oriented natural code:

Flower.new(:stock_item => si, ……)

2006-01-03
40ERROR

In the remove(bouquet) method, if in removing the flowers
from the stock_item table there aren’t enough flowers for
the 2nd through the last flowers returned from
bouquet.flowers, then the preceeding flowers that have
been removed from the stock will not be returned when the
exception has been thrown.

This could be a good place to introduce the
ActiveRecord.transaction class method to roll back the
changes when the exception is thrown,

2006-01-03
41TYPO

Missing s in the word ‘columns’:

The most important technique for preventing errors in
relational databases is to constrain columnS…..

2006-01-03
42SUGGEST

This is a stylistic issue.

In all the errors.add calls, in the RoR book, the attribute
having the error added is always a symbol, not a string.
For example, see page 66 of the RoR book.

2006-01-03
44SUGGEST

In describing the migrations, you could mention that you
can run arbitrary SQL code using the execute() method, even
though migrations handle most of the common tasks. You do
need to use execute() if after adding a column you want to
add a foreign key constraint on it, since migrations do not
support that yet.

2006-01-03
47SUGGEST

The URL for the LDAP RFC is pointing to an older one. Any
reason not to point to the latest RFC? While LDAP is now
described in multiple RFCs, maybe pointing to the newest,
master RFC would ne nice.

2006-01-03
134OK

Code example on line 24 should not use a split operation to read a CSV file. CSV parsers were discussed in the earlier chapter. So the best practice of using the CSV parser library should be used.

(Maik says: In this case it would be overkill and it would make both the server and the clients even more complicated. I have limited the Array returned by split() to a maximum of three entries which makes it easy to process messages containing commas.)

2006-03-05
178TYPO

In the last sentence of page 178:

> When we, e.g., call a method to draw a greeting card having the Id 42 and the message text on the back of the card (draw_greeting_card(4711, 42, ’Please, forgive me, honeybunch!’)) its XML-RPC representation will look like this:

the draw_greeting_card method is reference but the method is called draw_card.

2006-01-25
142TYPO

Section 4.1, “I’d Rather Use A Socket”
Contains this sentence:
“Fortunately, there are a off-the-shelf solutions available in Ruby’s standard distribution.”

Should be “there are a few”, or “there are”.

2006-01-28
270TYPO

Double periods ending last sentence of page: “if we’re to put the log file in the correct place..”

2006-01-28
197ERROR

exerpt:
get_report( )
returns a Hash containing a two-dimensional array for each flower
in stock.

“two-dimensional” should be “two element”

2006-01-28
254TYPO

With the basic Logger class, though, you don’t have may options.

“may” should be “many”

2006-05-18
274OK

This may just be my machine but I can’t get a service to start.
I keep getting:
Error 1053: The service did not respond to the start or control request in a timely fashion.

(Maikl says: I get this error message very often while developing the examples for this section. It is returned by Windows whenever an error occurs while starting or initializing a service. Carl has to double-check if everything is working properly. For example, the status monitor actually has to be up and running, otherwise the service_init() method will fail. The process has to be able to create the log file, all libraries have to be installed, and so on.)

2006-02-05
52TYPO

“The
(objectclass=) filter is comparable to SQL’s SELECT statement and
selects all entries not matter what attributes they have.”

Should probably read “…no matter…”

2006-02-07
57TYPO

“So, you
can use it with OpenLDAP, Netscape, and ActiveDirectory, e.g. ”…probably moved words around and overlooked this bit.

2006-02-07
17SUGGEST

It would be nice to provide a link to the patch that makes Ruby work with MySQL 4.1x. (no just the generic link to rails, takes hours to find the patch and apply it to the driver). Lack of MySQL out of the box support in Ruby is still an issue.

(Dave says: added)

2006-02-14
42OK

In the definition of the Bouquet class, the method “price” uses the inject method in order to sum up the amount. I have the books, “Agile Web Development with Rails” and “Rails Recipes” but none of those explain what the inject method does. I had to search the web and find a nice, simple explanation at http://rootr.net/rubyfaq-11.html. It may be useful if you have some sort of description of the inject method.

(Dave says: the author feels this is just part of the Ruby library. You’ll find information on this and other Ruby library functions, at ruby-doc.org)

2006-02-14
95TYPO

“A much better solution would be periodically to track the status of all
undelivered orders in our system and then infor m our customers about
all important events in the life of a deliver via e-mail or SMS messages. ”

seems like that should be “delivery” near the end there

2006-02-20
55TYPO

“The web shop team said that it’s not a big deal to create an user interface for the address book, but they asked you to create the corresponding backend services.”

shouldn’t that be “a user interface” ?

2006-02-20
60TYPO

“Obviously, everything is up an running.”

up and running

2006-02-20
102OK

mixed content sidebar goes off the bottom of the page

(Dave says: we fix layout errors such as this just before the book goes to press)

2006-02-20
158ERROR

RPC chapter link goes to the page before the chapter starts

221TYPO

“Consequentially, the situations today is a mess: ”

situation?

2006-02-22
155SUGGEST

On SMSes: Just to make the list complete, you can also send SMSes via Email. AFAIR it’s described in Pragmatic Project Automation (or at least on its blog).

2006-02-27
31ERROR

Massive SOL injection vulnerability!
Why not use parameterized statements?
Also, the code in this edition doesn’t feel as “Rubyish” as it could. Consider, for example, This approach for some update SQL (from the Ruby DBI docs):

sql = “insert into simple01 (SongName, SongLength_s) VALUES (?, ?)”
dbh.prepare(sql) do | sth |
1.upto(13) { |i| sth.execute(“Song #{i}”, “#{i*10}”) }
end

128TYPO

I think the sentence containing “but more often than not you’re better off, if you think about alter natives” should not have that final (second) comma.

2006-02-27
9TYPO

People who have been asked not to
be e-mailed should not get an e-mail.

Suggestion: lose the word “been”

2006-03-05
212SUGGEST

I could use a one-page blurb on generating ruby from XSD’s. It’s mentioned with the wsdl, but if I’m consuming (not producing) it would be handy to know.
On the other hand, it has paid for itself in time saved already!

30TYPO

Reads: “Before creating an Active Record class to mat the flowers table, we’ll…”

I think it should read: “Before creating an Active Record class to map the flowers table, we’ll…”

“map” instead of “mat”

2006-03-22
138SUGGEST

Fantastic book!
I’ve enjoied tle class to read fixed-length records: what about a class to write fixed-length records?

156SUGGEST

File 75, Line 30. entry.save would be better as entry.save! to have an exception raised, rather than false returned (and here ignored), in the case that the save is rejected by ActiveRecord, through, say, failed validations. Alternatively, test for and deal with the case where entry.save returns false.

Admittedly, if it is the DB which rejects, after AR accepts, an exception WILL be thrown, even with the current usage of entry.save(). However, someone will eventually revisit their LogEntry class and add validations, and then the existing StatusMonitor code will break, silently dropping some records.

This .save with no check is consistent in the book. As, it appears at a glance, is the use of models with no validation.

2006-05-18
91TYPO

“It might be empty for for elements associ-
ated with a namespace URI.”

Too many fors :)

2006-05-18
281284ERROR

I have yet to find out how the control script is “automatically generated”. The RDoc README for daemons suggests that you have to write the control script.

Dave says: The watcher_control script is the three preceding lines)

2006-05-18
141143TYPO

Code for “A list of 6 different objects” hash/list has “^” in the code, but “3” in the generated output.

2006-05-18
36TYPO

In the array with the 5 flowers the price of the sunflower is $0.4. In the select table upperside it costs only $0.3.

2006-05-18
33TYPO

“CRUD stands for Create, Retrieve, …”

On page 37, the R stands for Read…

2006-05-18
113OK

I don’t think the method “decode_markup” will work. The method gsub! returns nil if there is no substitution. The argument must contain all of the substitutions to avoid a nil. A solution is to use the construct: text = text.gsub()

(Maik says: I’ve tested the program (extract_todo.rb) and it works fine, because gsub!() changes the text in place. Hence, it doesn’t matter if it returns nil.)

2006-05-31
62SUGGEST

I fail to find the source code or cross reference per the reference to file 33?

113ERROR

Maik, I think you’ll want to check the code again for the previously reported problem with encode_markup.
The version inside extract_todo is different than in the book in that it returns the text variable in the end.

Another way to do this would be:
text.gsub(‘&’, ‘&’).gsub("‘“, ’'‘).gsub(’”’, ‘"’).gsub(‘<’, ‘<’).gsub(‘>’, ‘>’)

However, you’re still going to have a problem with this approach given that Person passes in self.address.to_xml to the tag method as value; all your opening and closing brackets for address will get encoded now!

102ERROR

to_event doesn’t appear to be setting the consignee to anything other than nil.

perhaps?

consignee = if !element.elements[‘consignee’].nil?
element.elements[‘consignee’].text
else
nil
end

89SUGGEST

(Sorry, please ignore #4161, p. 113 below; it was meant for pg. 89 and ‘encode_markup’ and I got confused with ‘decode_markup’ post.)

I think you will have a problem with encode_markup given that Person passes in self.address.to_xml to the tag method as value; all your opening and closing brackets for address will get encoded.

179TYPO

A really minor quibble, but on line 8 that prints the URL for the webrick-SSL really should specify ‘https://….’ instead of ‘http://….’. I concede that this is a trivial typo/oversight but it may catch others (like me) who tried to C&P the emitted URL into a browser and was briefly confused why it didn’t work.

Fantastic book, though.

1SUGGEST

For ActiveRecord, handling legacy databases has been an achilles heel (as others have pointed out). Recently one of the problems may have been solved with the CompositeKeys extension - see http://compositekeys.rubyforge.org/ - including this would make the book more ‘enterprisy’ for those that like that kind of thing

185TYPO

Table of XML-RPC types: Description of ‘String’ and ‘Base64’ types in second column (Values) are transposed.

28TYPO

From printed version 2006-6-16:

The first paragraph states “Similarly, exec() becomes execute() on line 18”, but the code listing has it on line 20.

118TYPO

From printed version 2006-6-16:

“namespace” should be hyphenated “name-space”, not “names-pace”

132TYPO

From printed version 2006-6-16:

“whitespace” should be hyphenated “white-space”, not “whites-pace”

119TYPO

From printed version 2006-6-16:

In the paragraph starting with “XPath expressions…”, both instances of “package-history” should be “parcel-history”

125TYPO

From printed version 2006-6-16:

There is a missing ‘]’ (right bracket) in the last line of code -
‘//event[state="delivered"]|//event[state=“picked-up”’
should be
‘//event[state="delivered"]|//event[state=“picked-up”]’

166TYPO

From printed version 2006-6-16:

In the second paragraph, “encode(string)” should be “escape(string)”

62-63TYPO

pg 63 mentions on line 8 of code listing on page 62 refers to code block with bind() using LDAP_AUTH_SIMPLE
That code doesn’t exist in the listing

Categories: