<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>DevChix » Book</title>
	
	<link>http://www.devchix.com</link>
	<description>Boys can't have all the fun</description>
	<pubDate>Sat, 04 Jul 2009 06:18:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/devchix/UtUz" type="application/rss+xml" /><feedburner:browserFriendly></feedburner:browserFriendly><item>
		<title>I Love Python: ReSTful DB CRUD dispatching using CherryPy</title>
		<link>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/</link>
		<comments>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 15:57:49 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Database]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Servers]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=230</guid>
		<description><![CDATA[CherryPy has been one of my favorite Python tools for several years. It should be mentioned here that a ReSTful dispatcher could easily be written in web.py, or pylons as well, and even comes for free in the latest TurboGears implementation. 
But if you&#8217;re looking for a small, easily manageable and extremely dynamic ReST dispatching [...]]]></description>
			<content:encoded><![CDATA[<p>CherryPy has been one of my favorite Python tools for several years. It should be mentioned here that a ReSTful dispatcher could easily be written in web.py, or pylons as well, and even comes for free in the latest TurboGears implementation. </p>
<p>But if you&#8217;re looking for a small, easily manageable and extremely dynamic ReST dispatching solution without the heft of an entire web framework, I&#8217;m about to show you how CherryPy can help you in three different ways, depending on your model.</p>
<p>Assuming this mapping:</p>
<p>HTTP GET or HEAD = DB Read<br />
HTTP POST = DB update<br />
HTTP PUT = DB insert<br />
HTTP DELETE = DB delete</p>
<p>Let&#8217;s also standardize on one common method across all examples, for determining the HTTP request type, and matching it to the function of the same name. Here is the full code snippet for accomplishing this task:</p>
<pre>
methods = ('OPTIONS','GET','HEAD','POST',
'PUT','DELETE','TRACE','CONNECT')

if cherrypy.request.method not in self.methods:
    raise cherrypy.HTTPError(400,'Bad Request')

# If request method is HEAD, return the page handler
# for GET, and let CherryPy take care of dropping
# the response body
method = cherrypy.request.method

if cherrypy.request.method == "HEAD":
    method = "GET"

http_method = getattr(self,method)

#print "HTTP Method: %s" % method

result=(http_method)(args,kwargs)
</pre>
<p>In our examples, we&#8217;re going to shorten this to:</p>
<pre>
http_method = getattr(self.m,cherrypy.request.method)
return (http_method)(args,kwargs)
</pre>
<p>All of this essentially determines how HTTP was called (GET/PUT/POST/DELETE), and calls the method in a class which exactly matches this name (self.GET(), self.PUT(), etc)<br />
When you see this code, know that it&#8217;s just the HTTP method resolving code. </p>
<p>Now for the fun. Let&#8217;s look at the dispatcher options we have. </p>
<h3>Way 1: A hard-coded URL pointing to fixed resources: </h3>
<p>CherryPy can be used in a manner similar to this to establish a fixed URL, and corresponding resources, driven from predefined classes instantiated in the &#8216;root&#8217; hierarchy:</p>
<pre>
import cherrypy

class ReSTPaths1:
	@cherrypy.expose
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()

	def GET(self):
		return "In GET 1.."

class ReSTPaths2:
	@cherrypy.expose
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()

	def GET(self):
		return "In GET 2.."

class ReSTPaths3:
	@cherrypy.expose
	def index(self,client_id=None):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)(client_id)

	def GET(self,client_id=None):
		return "IN Get 3, your client_id is %s\n" % (client_id)

cherrypy.server.socket_port=8081

root=ReSTPaths1()
root.client = ReSTPaths2()
root.client.address = ReSTPaths3()
cherrypy.quickstart(root)
</pre>
<p>Once this is running, the URL to invoke it looks like this:<br />
http://localhost:8081/<br />
http://localhost:8081/client/<br />
http://localhost:8081/client/address/<br />
http://localhost:8081/client/address/?client_id=34567<br />
http://localhost:8081/client/address/34567</p>
<p>Output looks something like this:</p>
<pre>
In GET 1..
In GET 2..
IN Get 3, your client_id is None
</pre>
<p>If you&#8217;re new to CherryPy or Python in general, I&#8217;ll reiterate for you how we are calling the GET method in our class. </p>
<p>When we issue this request, we&#8217;re issuing what HTTP calls a GET request:</p>
<p>http://localhost:8081/</p>
<p>The CherryPy service above, listening on port 8081, calls the index() method on the root class. The root class was set to:</p>
<p>root=ReSTPaths1()</p>
<p>at the bottom of that file. The index() method from the ReSTPaths1 Class looks like this, at the top of that file:</p>
<pre>
	def index(self):
		http_method = getattr(self,cherrypy.request.method)
		return (http_method)()
</pre>
<p>If we were to insert a print cherrypy.request.method statement before the return, we would see it set to &#8220;GET&#8221;. </p>
<p>getattr simply says: &#8220;get me the function name in self, matching the string &#8220;GET&#8221;.<br />
it returns a reference to self.GET(), which is set directly below the index:</p>
<pre>
	def GET(self):
		return "In GET 1.."
</pre>
<p>Notice that the index() method has a <strong>@cherrrypy.expose</strong> decorator above it. This makes the index method callable by the public. The GET method does not have it, which means we could never invoke the GET method by typing:</p>
<p>http://localhost:8081/GET</p>
<p>If you try this, you&#8217;ll get a 404 Not Found error, because it&#8217;s not visible through the CherryPy interface.</p>
<p>GET() has to be invoked through index(), which means GET can only be called if an HTTP GET request is issued. If we posted form data to this same URL from, say, a form entry asking people for data input, we would need to add a POST method to this ReSTPaths1() class, to receive the POST data entered in the form fields.</p>
<p>Now back to our example:</p>
<p>In this example, no part of the URL or associated resources are dynamic, in either initialization or run time. This is fine, and suits the needs of most ReSTful CRUD interfaces. </p>
<h3>Way 2: URL paths and associated components dynamically set once, upon dispatcher init/startup: </h3>
<p>Now let&#8217;s say we want to determine the contents of the root, and therefore the URLs and associated resources for our ReSTful interface, dynamically during initialization/startup. </p>
<p>We can assign the root setting by using a Python metaclass to generate classes in our CherryPy startup code, and set the root components to each generated class. This goes beyond the average needs for CRUD access, but it&#8217;s such a nice implementation that I must show it off:</p>
<pre>
import cherrypy

class MetaCRUD(type):
	@cherrypy.expose
	def index(cls):
		http_method = getattr(cls,cherrypy.request.method)
		return (http_method)()

	def GET(cls): return "In class ", cls.__name__, ', received a GET request.'

	def PUT(cls): return "In class ", cls.__name__, ', received a PUT request.'

	def POST(cls): return "In class ", cls.__name__, ', received a POST request.'

	def DELETE(cls): return "In class ", cls.__name__, ', received a DELETE request.'

baseCRUD = MetaCRUD('baseCRUD',(),{})
root = baseCRUD

dynamic_class = {}

for d in ['legacy_dbi','new_dbi','some_other_dbi']:
	dynamic_class[d] = MetaCRUD(d,(),{})
	setattr(root,d,dynamic_class[d])

cherrypy.server.socket_port=8081
cherrypy.quickstart(root)
</pre>
<p>Here we&#8217;re using a metaclass, with CherryPy exposed methods, to generate a dictionary of dynamic classes. We set the root.classname = the_new_class by using the setattr() method. </p>
<p>After initialization, URL components and resources are fixed in this model. But wow, the awesome power we have during initialization, in 28 lines really rocks. I wrote this in 30 minutes, and realized again why I am so head-over-heels in love with this language. </p>
<p>When we hit these URLs:</p>
<pre>
http://localhost:8081/
http://localhost:8081/legacy_dbi/
http://localhost:8081/new_dbi/
http://localhost:8081/some_other_dbi/
</pre>
<p>We see this output:</p>
<pre>
In class baseCRUD, received a GET request.
In class legacy_dbi, received a GET request.
In class new_dbi, received a GET request.
In class some_other_dbi, received a GET request.
</pre>
<p>Let&#8217;s issue a POST request via curl, on the command line. The response is returned:</p>
<pre>
[gloriajw@g-monster ~]$ curl http://localhost:8081/some_other_dbi/ -d ""
In class some_other_dbi, received a POST request.
</pre>
<p>This model could be used for, say, reading the contents of the Postgres template1 databases list or the mysql &#8217;show databases&#8217; command, and auto-generating a ReSTful CRUD interface for each. Access of each resources can be controlled via HTTP Auth methods. This is a great solution to providing, and restricting, legacy database access for new processes through a standard interface. </p>
<h3>Way 3: Live, ever-dynamic determination of URL and associated component: </h3>
<p>Some ReSTful URL models may need to be &#8216;run-time dynamic&#8217;, especially in the case where databases are dynamically created, and the associated resources per new database could vary. There is a simple example of a dynamic URL and resource model:</p>
<pre>
import cherrypy
import pprint

class ReSTPaths:
	@cherrypy.expose
	def __init__(self):
		pass

	@cherrypy.expose
	def client(self,*args,**kwargs):
		return "Your HTTP method was %s. Your args are: %s and your kwargs are: %s\n" \
		% (cherrypy.request.method, pprint.pformat(args), pprint.pformat(kwargs))

	@cherrypy.expose
	def address(self,*args,**kwargs):
		return "Your HTTP method was %s. Your args are: %s and your kwargs are: %s\n" \
		% (cherrypy.request.method, pprint.pformat(args), pprint.pformat(kwargs))

cherrypy.quickstart(ReSTPaths())
</pre>
<p>This allows for dynamic URLs such as:<br />
http://localhost:8080/client/address/34567<br />
http://localhost:8080/client/address?client_id=34567<br />
http://localhost:8080/address/client?client_id=34567<br />
http://localhost:8080/address/client/34567<br />
http://localhost:8080/address/anything/anything_else</p>
<p>The output from this code looks like this:</p>
<pre>
Your HTTP method was GET. Your args are: ('address', '34567') and your kwargs are: {}
Your HTTP method was GET. Your args are: ('address',) and your kwargs are: {'client_id': '34567'}
Your HTTP method was GET. Your args are: ('client',) and your kwargs are: {'client_id': '34567'}
Your HTTP method was GET. Your args are: ('client', '34567') and your kwargs are: {}
Your HTTP method was GET. Your args are: ('anything', 'anything_else') and your kwargs are: {}
</pre>
<p>Notice that we only have keyword args (kwargs) when we pass a named parameter, such as client_id=34567</p>
<p>Let&#8217;s try a POST request from curl, on the command line:</p>
<pre>
[gloriajw@g-monster ~]$ curl -d "something_else=whatever_i_want" http://localhost:8080/address/anything/anything_else
Your HTTP method was POST. Your args are: ('anything', 'anything_else') and your kwargs are: {'something_else': 'whatever_i_want'}
</pre>
<p>In this code, the sky is the limit. You can place whatever code you like in these methods, dynamically creating classes and resources as needed, letting them only persist until the result is returned. This may add some inefficiency, but in exchange offer more secure network resources.</p>
<p>Code is attached, Enjoy!</p>
<p>Gloria</p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restfixedargs.py">http://www.devchix.com/wp-content/uploads/2009/04/restfixedargs.py</a></p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restmeta.py">http://www.devchix.com/wp-content/uploads/2009/04/restmeta.py</a></p>
<p><a href="http://www.devchix.com/wp-content/uploads/2009/04/restvarargs.py">http://www.devchix.com/wp-content/uploads/2009/04/restvarargs.py</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/04/19/i-love-python-restful-db-crud-dispatching-using-cherrypy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Creative Commons license, and change.gov: Our new president gets it!</title>
		<link>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/</link>
		<comments>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 20:23:58 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=189</guid>
		<description><![CDATA[I was really excited and moved to see this:
http://change.gov/newsroom/entry/towards_a_21st_century_government/
This copyright license affects most content on the website change.gov, guaranteeing transparency and the feedom to redistribute and discuss it&#8217;s content. 
All I can say is, wow. This president not only believes in transparency, but understands how to implement it using existing tools and conventions. He understands [...]]]></description>
			<content:encoded><![CDATA[<p>I was really excited and moved to see this:</p>
<p><a href="http://change.gov/newsroom/entry/towards_a_21st_century_government/">http://change.gov/newsroom/entry/towards_a_21st_century_government/</a></p>
<p>This copyright license affects most content on the website change.gov, guaranteeing transparency and the feedom to redistribute and discuss it&#8217;s content. </p>
<p>All I can say is, wow. This president not only believes in transparency, but understands how to implement it using existing tools and conventions. He understands the spirit of Open Source software development, and everything that has come about since this movement began. Imagine an &#8220;Open Government&#8221;, genuinely implemented and influenced by the people, and it&#8217;s hard not to want to get involved.</p>
<p>The change.gov web site has a very nice, simple form, requesting your ideas and suggestions. They already have proposals for nationwide fiber optic broadband, automation and transparency in the patent process, and automation of health insurance data to bring healthcare costs down. There are many more places where technology can automate away inefficient and error prone processes. </p>
<p>We here on DevChix all know how technology has changed our lives. Let them know how it can change a nation. Submit your ideas and suggestions, and let&#8217;s help educate and influence this new administration.</p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/12/02/the-creative-commons-license-and-changegov-our-new-president-gets-it/feed/</wfw:commentRss>
		</item>
		<item>
		<title>From Python 2.6 to PHP 5.2: A circuitous journey</title>
		<link>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/</link>
		<comments>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 20:02:08 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[People]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=187</guid>
		<description><![CDATA[When I started heavily using PHP 5.2 (not by choice, I&#8217;ll admit), I was impressed, but I suffered from some incorrect assumptions about what PHP5 is and is not capable of doing. The good news is that it is more object oriented than it&#8217;s predecessor, but has some caveats to consider. Here are some things [...]]]></description>
			<content:encoded><![CDATA[<p>When I started heavily using PHP 5.2 (not by choice, I&#8217;ll admit), I was impressed, but I suffered from some incorrect assumptions about what PHP5 is and is not capable of doing. The good news is that it is more object oriented than it&#8217;s predecessor, but has some caveats to consider. Here are some things to be aware of when switching from a pure OO language to PHP5:</p>
<p>1: A nonexistent PHP array key generates no error or warning. When trying to iterate over a nonexistent array key, a warning occurs. In other languages, both of these conditions throw an exception.</p>
<p>Try this code for example:</p>
<pre>
&lt;?
$dictionary=array('one'=>'got one','two'=>'have two','four'=>'missing three?');
foreach (array_keys($dictionary) as $key)
{
	print "Key is:".$key.", value is:".$dictionary[$key]."\n";
}
print "Try undefined key three, no warning occurs:".$dictionary['three']."\n";
foreach ($dictionary['three'] as $value)
{
	print "Now we're iterating over a nonexistent key:";
	print "Key is: three, value is:".$dictionary['three']."\n";
}
?>
</pre>
<p>Running it results in this output:</p>
<pre>
php test.php
Key is:one, value is:got one
Key is:two, value is:have two
Key is:four, value is:missing three?
Try undefined key three, no warning occurs:

Warning: Invalid argument supplied for foreach() in /root/test.php on line 8
</pre>
<p>If it is vital to me to make sure I am aware of missing keys, I only have two choices. If I need a proactive solution, I have to use the array_key_exists() function to do existence checking before use. If I want a reactive solution, I  write a log scanner, to pick up on these warnings. In every other OO language I have used, an exception was thrown for this condition, and my exception handling determined if the error was vital enough to have to exit immediately or not. This seems like a more efficient way to handle this condition. I would imaging PHP5 does not do this because of it&#8217;s need to be backward compatible with PHP4, but this is a guess. </p>
<p>It would be wonderful to have a -OO flag for PHP, which gives you the option to run PHP and expect more standard, stricter OO behavior in these instances. </p>
<p>2: Warnings cannot be &#8220;caught&#8221; like exceptions. Exceptions and warnings are distinctly separate beasts, and never the twain shall meet. Fine, I thought, maybe I could detect warnings similar to how we detect errors. But it seems like warnings cannot be detected when they happen. There is no PHP code I know of which can check if a warning had occurred in runtime. I tried to detect it using array error_get_last() but to no avail. if you know how, post your trick here.</p>
<p>3: In PHP, &#8216;true&#8217; evaluates to an integer &#8216;1&#8242;. To get the boolean &#8216;true&#8217; value from a &#8216;true&#8217; statement, one needs to var_export() a true statement. Similarly, or maybe not, &#8216;false&#8217; evaluates to no output. Here is an example:</p>
<pre>
&lt;?
print "\nThe raw value of a true statement in PHP:".true;
print "\nThe raw value of a false statement in PHP:".false;
print "\nThe exported value of a true statement in PHP:".var_export(true,true);
print "\nThe exported value of a false statement in PHP:".var_export(false,true);
print "\n";
?>
</pre>
<p>And the output:</p>
<pre>
The raw value of a true statement in PHP:1
The raw value of a false statement in PHP:
The exported value of a true statement in PHP:true
The exported value of a false statement in PHP:false
</pre>
<p>This may not be noticeable to you in a standard expression. But if you&#8217;re doing funky stuff, like using the evaluated expression values as key references into the dictionary of a decision tree, for example, 1 does not equal &#8216;true&#8217;, and the difference matters quite a bit. </p>
<p>4: Long running processes with recursive circular references (such as Doctrine code) run out of memory. This is documented in many places, and the free() function works sometimes. A fix is coming in PHP 5.3. The foolproof solution for my code in production today (youch!) is to periodically restart the daemon. If you&#8217;re cringing right now, know that you&#8217;re not cringing alone. </p>
<p>There may be a part II to this article. Feel free to add your own PHP5 observations. </p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/11/20/from-python-26-to-php-52-a-circuitous-journey/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review, “Pro Active Record”</title>
		<link>http://www.devchix.com/2008/03/12/book-review-pro-active-record/</link>
		<comments>http://www.devchix.com/2008/03/12/book-review-pro-active-record/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 01:39:09 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/03/12/book-review-pro-active-record/</guid>
		<description><![CDATA[Published by Apress
By Kevin Marshall, Chad Pytel, Jon Yurek
Book Info
Sample Chapter: Ch. 01 - Introducing Active Record
Table of Contents 
Years ago when I was in PHP Land (now I travel quite a bit more! haha), I strugged for months with how to write a good ORM . It was tough, because I wanted to abstract [...]]]></description>
			<content:encoded><![CDATA[<p>Published by Apress<br />
By Kevin Marshall, Chad Pytel, Jon Yurek<br />
<a href="http://apress.com/book/view/9781590598474">Book Info</a><br />
<a href="http://apress.com/book/downloadfile/3712">Sample Chapter: Ch. 01 - Introducing Active Record</a><br />
<a href="http://apress.com/book/downloadfile/3711">Table of Contents</a> </p>
<p>Years ago when I was in PHP Land (now I travel quite a bit more! haha), I strugged for months with how to write a good ORM . It was tough, because I wanted to abstract the &#8220;boring logic&#8221; of retrieving records from a database without writing SQL but still remain flexible enough. I never really came up with a good model. I used the DAO from &#8220;extreme php&#8221; library which I think was a knock off from java. It was ok, but I still didn&#8217;t feel like I had &#8220;arrived&#8221;. </p>
<p>When I discovered Ruby on Rails, I found ActiveRecord. Ahh HA! Finally, this is what I was looking for. At first I thought it was part of Rails, but its not. Its a standalone library and you can use it with straight up ruby scripts. </p>
<p>I got a review copy of &#8220;Pro Active Record&#8221; some time ago and read it some when I got it, then some later, and now I am going to officially write up a review! </p>
<p>If you do anything with Active Record, get this book. The things that are briefly mentioned in most Rails books are described in detail in this book.<br />
<strong><br />
Chapter 1 -  Introducing Active Record</strong></p>
<p>Most of the time, the first chapters of a book are boring to me. I don&#8217;t need another &#8220;History of the Internet&#8221;  or how &#8220;HTML was developed&#8221; &#8230; blah blah. But this one, the story is only 1 page. And it actually has some introductory scripts on using Active Record, so you can see right away how it works. It also explains the benefits of MVC and why ORMs are good. Some people still don&#8217;t get it!</p>
<p><strong>Chapter 2 - Active Record and SQL</strong></p>
<p>This chapter helps you translate the &#8220;sql in your head&#8221; to how to write it with Active Record. I&#8217;ve used Active Record so much that now I have forgotten most of my SQL,   which is kind of embarrassing. :) I now find writing sql tedious and boring! I would have actually called this chapter &#8220;Demystifying Active Record&#8221; since it explains why all the dynamic finders work. You&#8217;ll also find transactions and locking explained here.</p>
<p><strong>Chapter 3 - Setting up Your Database</strong></p>
<p>Migrations! The Awesome Thing that can turn into a nightmare for large rails projects with multiple developers&#8230;. definitely have to decide on some best practices with your team on this one. The chapter has only one thing to say about this &#8212; assume any checked in migration has already been run by your team and the migration should not be edited and checked back in! You&#8217;ll have to make another migration file with your changes.</p>
<p><code>[tip]<br />
Nola&#8217;s Note: When you make a migration, test it both UP and DOWN!! Here&#8217;s what I do &#8212;<br />
write a migratiion<br />
rake db:migrate   (go up to the version with new code)<br />
rake db:migrate VERSION=n-1,  (go to version before the latest)<br />
rake db:migrate  (back to lastest)<br />
rake db:migrate VERSION=0  (back to blank db)<br />
rake db:migrate (back to latest)<br />
[/tip]</code></p>
<p>Just to be sure its all good &#8212; even on a new database!<br />
<strong><br />
Chapter 4 - Core Features of Active Record</strong></p>
<p>Now is the fun stuff - Callbacks. This is magic. This makes Active Record so flexible, and is one thing I could never figure out how to do with my PHP ORMs. I use call backs to set defaults for fields. If its just a straight default, then I set it in the database but if I need to make a decision, (if this field then this field..) then I can use it in a callback.</p>
<p>Associations - at first this is very confusing! I don&#8217;t know how many times I got &#8220;has_many&#8221; and &#8220;belongs_to&#8221; mixed around in the beginning. </p>
<p>Validations - Awesome. I had to do some ruby code without a database and I really really really missed the validations. It took me like 5x longer than it should! Understanding all of these validation methods will make your life so much more enjoyable. I really really hate doing boring, repetitive stuff&#8230;it seems so wasteful to me.<br />
<strong><br />
Chapter 5 - Bonus Features</strong></p>
<p>Everybody likes a bonus and this isn&#8217;t even the last chapter of the book. </p>
<p>Java people will like the Active Record Observers &#8212; seems a little AOP to me (aspect orienteted programming) and something I probably have neglected to use to their fullest extent. </p>
<p>Acting up &#8212; Learn how to &#8220;save time&#8221; with the &#8220;acts_as&#8221; magic:  List, Tree, Nested Sets.  If your data needs these structures, you got it made. I can imaging how much longer it would take to write this stuff in perl or php. </p>
<p>Composed of - I haven&#8217;t used this, but this looks like a good way to make sensible objects out of database tables. There is quite a bit of explanation and examples of this, it will come in handy.</p>
<p>There are a few other in depth explanations of things, such as method_missing which is how alot of the magic happens. Rock on.<br />
<strong><br />
Chapter 6 - Active Record Testing and Debugging<br />
</strong><br />
Ahh yes, Testing. My favorite subject. My friends who know how much I love testing say I am sick. I must have an inner need to PROVE I am right or something, haha. </p>
<p>The chapter goes into depth about using test_unit with Active Record, sadly  no RSpec. But, it does go into all the error messages that Active Record throws so you can write good try/catch blocks and make very exact error messages (probably best logged for the admin rather then displayed to the user!) <strong></p>
<p>Chapter 7 - Working with Legacy Schema</strong></p>
<p>Here&#8217;s how you work with that old database that just won&#8217;t die&#8230; or that management won&#8217;t let you totally redo. Active Record follows some of the principles of Rails &#8220;convention over configuration&#8221; &#8230; relying on table and column naming conventions to figure out how to build your object&#8230;.but still giving you a way out if you want your tables singular and your primary id field called &#8220;myawesomeid&#8221; instead of &#8220;id&#8221; </p>
<p> I&#8217;ve used some of these things on an older database and it was possible! Not too bad if thats what you have to work with.<br />
<code><br />
[soapbox]<br />
Some people find this annoying &#8220;oh gosh! my library can&#8217;t make decisions for me! OMG! That sucks&#8221; ..  to that I say, &#8220;Umm ok. But if you follow these conventions then I can come into your project and know exactly what is going on&#8221; &#8230; like with web standards, we all harp on how IE and FF do things differently, yet people want to bellyache about Active Record preferring to have plural names and id field called &#8220;id&#8221;.  Right. </p>
<p> Follow the dang convention and find something worth complaining about to complain about. :)<br />
[/soapbox]</code><br />
<strong><br />
Chapter 8 - Active Record and The Real World</strong></p>
<p>This chapter goes into depth about the library and encourages you to go read the Active Record code. Always a good idea to know what it is you are using :)  I&#8217;ve actually learned ruby better by reading source code. The chapter walks you through basic structure of the files. Very cool. </p>
<p><code>[soapbox]<br />
I used to work at a place that didn&#8217;t like any &#8220;outside code&#8221;  because they were afraid &#8220;OMG &#8230; it will send our passwords to Russia!&#8221; &#8230;  ok, well I am not an idiot. I read over any code that I use that I didn&#8217;t write. I look at the tests to see if I am using it right. I even RUN the tests so I can be sure its working as advertised.<br />
[/soapbox]</code></p>
<p>Alternatives to Active Record - with EXAMPLES! If something about Active Record doesn&#8217;t set too well with you, take a look at the alternatives. Sometimes I look at the alternatives and decide that the first wasn&#8217;t so bad after all. You&#8217;ll find examples of DBI, Og, ActiveRelation.</p>
<p>Finally a section on Q and A finishes up this book. The Appendix has a complete reference of ActiveRecord methods to make this book a well rounded reference, tips, documentation and very handy to have at your desk! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/03/12/book-review-pro-active-record/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: Pro Drupal Development</title>
		<link>http://www.devchix.com/2007/08/12/book-review-pro-drupal-development/</link>
		<comments>http://www.devchix.com/2007/08/12/book-review-pro-drupal-development/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 20:28:30 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/08/12/book-review-pro-drupal-development/</guid>
		<description><![CDATA[Book Site &#124; Sample Chapter: The Theme System &#124; Table of Contents
Many of you are aware of my current total infatuation with Ruby, and that I&#8217;ve used PHP for about 6 years and at one point decided I hated PHP&#8230;until, I needed it for a quick one-off page and then realized that PHP had its [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.apress.com/book/bookDisplay.html?bID=10258">Book Site</a> | <a href="http://www.apress.com/book/supplementDownload.html?bID=10258&amp;sID=4237">Sample Chapter: The Theme System</a> | <a href="http://www.apress.com/book/supplementDownload.html?bID=10258&amp;sID=4233">Table of Contents</a></p>
<p>Many of you are aware of my current total infatuation with Ruby, and that I&#8217;ve used PHP for about 6 years and at one point decided I hated PHP&#8230;until, I needed it for a quick one-off page and then realized that PHP had its place. Then again, <a href="http://www.rubygeek.com/2007/05/09/get-er-done/">I was totally frustrated with Ruby</a> when making my <a href="http://www.apieceacake.com">moms bakery site</a> and then turned to <a href="http://drupal.org/">Drupal</a> and <a href="http://gallery.menalto.com/gallery">Gallery</a> (another fine PHP project), which saved my bacon and I got a website and photo gallery up in a weekend. So, PHP and I have had our moments but I&#8217;m not abandoning it!<br/></p>
<p>Drupal powers some big sites, its not just for joe smoe&#8217;s blog. This is an interesting page about <a href="http://drupal.org/handbook/is-drupal-right-for-you">Is Drupal Right For You?</a> and if you are wondering if its something that would even work for you.</p>
<p>I was excited to get my hands on a review copy of Pro Drupal Development. Its no secret that coders hate documentation and Drupal has one of the most complete online documentation I&#8217;ve seen for an Open Source project, but its almost too hard to find what you need amongst so much. The Pro Drupal Book is a godsend for the drupal programmer, new and experienced alike. I wish it was written a year ago!</p>
<p>The book starts off with a quick overview of how Drupal is structured and defines terms such as hooks, node and blocks in just 10 pages. Chapter 2 is a A step-by-step tutorial with making a module. That is a great idea to start off quickly writing code. It get the reader involved and hands on. I really tire of books that have to start off with the history of the internet, html and how things have evolved. Get to the code dangit!! Kudos to the Authors for that! Chapter 3 gets into module specific settings, like how to get your module to show up on the admin page and storing user settings that your module needs.</p>
<p>After you&#8217;ve had some experience with the code then the book goes into details on the specific parts of Drupal:</p>
<ul>
<li>
    Menu System
  </li>
<li>
    Databases
  </li>
<li>
    Users
  </li>
<li>
    Nodes
  </li>
<li>
    Themes
  </li>
<li>
    Blocks
  </li>
<li>
    Form API
  </li>
<li>
    Filter System
  </li>
<li>
    Searching and Indexing
  </li>
<li>
    Files
  </li>
<li>
    Taxonomy
  </li>
<li>
    Caching
  </li>
<li>
    Sessions
  </li>
<li>
    JQuery
  </li>
<li>
    Localization
  </li>
<li>
    Using XML-RPC
  </li>
</ul>
<p>Drupal is a pretty amazing framework, when I read the code I say &#8220;why didn&#8217;t I think of that?&#8221; &#8230; the module and hook system is genius.</p>
<p>Then some more general topics:</p>
<ul>
<li>
    Writing Secure code
  </li>
<li>
    Development Best Practices
  </li>
<li>
    Optimizing Drupal
  </li>
<li>
    Installation Profiles
  </li>
</ul>
<p>One of the chapters I skipped ahead to read was The Form API. In my years of PHP I&#8217;ve often tried to come up with a framework for doing forms and I wanted to see how they did it. This chapter follows a tutorial style as well. The Form API allows you to define fields, their label, their value, description. Some frameworks take the template approach, where you hammer out your HTML. Some are more configuration based like Drupal making a multi-dim array with keys and values. I can see advantages to both. There is a hook function for validation which allows you to write your validation checks.</p>
<p>PHP gets a bad wrap for security, partly because its pretty easy to learn PHP and newbies don&#8217;t always realize what they are doing. There is a chapter devoted to security and includes even some things I didn&#8217;t know about &#8212; encoding mail headers. The Form API is very secure,&nbsp; one thing it does is check values that come from dropdowns were actually in the options and it wasn&#8217;t something that the hacker made up.</p>
<p>Developer Best Practices are great for the new developer, it talks about using cvs, tags, branches. It talks about how to create and apply patches (hint - you can contribute back to drupal). That is awesome. Alot of open source projects are like &#8220;HELP us, submit patches!&#8221; and the new user is left with uhhhhhh..how?</p>
<p>Caching is another interesting chapter. You will learn&nbsp; how caching works and how Drupal Core uses it. There is a Cache API that has methods for module creators to make their modules faster.</p>
<p>JQuery &#8230; I am not sure if I like it or not, but its part of Drupal 5! I skipped ahead to this chapter to see what its all about. There is a javascript hook built into Drupal making it easy to add, thats pretty cool.</p>
<p>One thing I found lacking in the book is anything about Testing. There are few pages on debugging and some modules to help with testing, but I would like to see more. At least some talk about selenium, which is great for a site made with any framework/cms.</p>
<p>Over all, Thanks APress for another great book!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/08/12/book-review-pro-drupal-development/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Let’s All Evolve Past This: The Barriers Women Face in Tech Communities</title>
		<link>http://www.devchix.com/2007/06/09/let%e2%80%99s-all-evolve-past-this-the-barriers-women-face-in-tech-communities/</link>
		<comments>http://www.devchix.com/2007/06/09/let%e2%80%99s-all-evolve-past-this-the-barriers-women-face-in-tech-communities/#comments</comments>
		<pubDate>Sun, 10 Jun 2007 05:56:15 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[CherryPy]]></category>

		<category><![CDATA[Events]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/06/09/let%e2%80%99s-all-evolve-past-this-the-barriers-women-face-in-tech-communities/</guid>
		<description><![CDATA[Topics of this Article:

Introduction
The less obvious
Why do women-only tech groups exist?
The Community
Communication Style
Awareness of and accountability for behavior not found in mixed gender tech groups/gatherings.
Men are generally very good at ignoring bad behavior.
Protective behavior within the community.
The few vocal, and many silent, members.
Women during tech discussions
Did you know?
Suggestions for a more women-friendly community.
Tips for communicating [...]]]></description>
			<content:encoded><![CDATA[<p>Topics of this Article:</p>
<ul>
<li><a href="#1">Introduction</a></li>
<li><a href="#2">The less obvious</a></li>
<li><a href="#3">Why do women-only tech groups exist?</a></li>
<li><a href="#4">The Community</a></li>
<li><a href="#5">Communication Style</a></li>
<li><a href="#6">Awareness of and accountability for behavior not found in mixed gender tech groups/gatherings.</a></li>
<li><a href="#7">Men are generally very good at ignoring bad behavior.</a></li>
<li><a href="#8">Protective behavior within the community.</a></li>
<li><a href="#9">The few vocal, and many silent, members.</a></li>
<li><a href="#10">Women during tech discussions</a></li>
<li><a href="#11">Did you know?</a></li>
<li><a href="#12">Suggestions for a more women-friendly community.</a></li>
<li><a href="#13">Tips for communicating with Women in Tech environments.</a></li>
</ul>
<p><strong><a name="1"></a>Introduction</strong></p>
<p>This subject has been on the minds of many tech women for years. The issue is discussed regularly, almost cyclically at times, as we spin our collective wheels to try to find causes and solutions. I was reluctant to write about it, since I find the subject matter daunting, and the problem almost insurmountable at times. But three different sources approached me simultaneously, asking for this article. This article feels as if it is manifesting through me rather than from me, as a collective opinion and observation from the many tech women with whom I&#8217;ve worked and spoken. So many factors are in play when discussing this issue that I can only hope to address many of them without writing a tome.  </p>
<p>My tendencies are to pick up on patterns, in human interaction, in data, in almost everything. I am a computer science/math major, and my brain loves to seek out the unobvious patterns in whatever I am observing. One of my favorite pastimes is to figure out broken elevator algorithms: what event causes the doors to close too quickly, how are the cars distributed amongst the people requesting the elevators, etc. One of the not-so-favorite puzzles my brain likes to do is to pick up on patterns of human behavior from both men and women which affect how tech women are treated both on and off the job. This article is all about the patterns I and other women have found in human interaction, office and online environments, which make them less conducive to tech women participation. </p>
<p><strong><a name="2"></a>The less obvious</strong></p>
<p>I won&#8217;t be addressing the more obvious problems affecting women in tech environments such as the pay scale gap between women and men, the blatantly inappropriate sexism and personal harassment that has taken place, and persists. My reasons are because I feel these issues have been properly and effectively addressed by other women in tech (they&#8217;re not resolved by any means, but at least public awareness is rising). With this article, I am attempting to address the less obvious or unobvious reasons why some tech environments are intolerable for many women. </p>
<p>The material for this article came about through my participation in both women-only and mixed gender groups of many kinds. When I wonder why tech groups aren&#8217;t tolerable for many women, I look at the inverse of the problem: What makes women-only tech groups more tolerable for women? My observations follow. </p>
<p><strong><a name="3"></a>Why do women-only tech groups exist?</strong></p>
<p>Over the years I had participated in many different types of women-only groups. Women-only drumming groups, women-only political groups, women-only tech groups, have all provided what women consider to be a &#8220;safe haven&#8221; to freely learn these arts, share ideas, expose each other to paid &#8220;gigs&#8221;, and help each other accomplish tasks. Women in these groups usually had nothing else in common except for the fact that they (1) were female, and (2) shared an interest and experience in drumming/politics/tech. Their professions, ages, skill levels, hobbies, sexual orientations, life experiences, marital status, children/grandchildren/no children, everything else about these women varied vastly. </p>
<p>My brain began to try and pick up on patterns which would explain why all of these different types of women feel as if they need a women-only group, and what such a group can provide that a mixed gender group cannot. Here are my observations. </p>
<p><strong><a name="4"></a>Community plays an important and prevalent role in women-only/women-friendly groups.</strong></p>
<p>No matter the group or the reason for gathering, _all_ of the women-only, and most of the successful women-friendly groups to which I have belonged had a strong sense of community. They make a tremendous effort to communicate well, to be fair with each other, and to provide support related to the groups goals, sometimes even extending outside of the groups goals.</p>
<p>This mindset is so common that women come to expect it when joining these groups, and foster it once they have joined. The implied message is that a strong, focused, collective effort will be spent to run things fairly and treat all members equally, and collective discussion happens when this is not accomplished. This is the lure to women-only groups.</p>
<p><strong><a name="5"></a>Communication style is directly affected by this sense of community</strong></p>
<p>I have never seen a woman harshly criticize another woman in these groups. Never have I seen or heard anything like &#8220;You suck&#8221;, &#8220;You&#8217;re wrong, idiot&#8221; when women in these groups communicate. Differences are usually discussed in a civilized manner. There is the occasional strong disagreement or ousting of a member now and again, but it happens after a discussion involving the entire group, and an effort to work out their differences. I am sure harsh criticism happens somewhere in some women&#8217;s groups. But I am also sure that it&#8217;s not tolerated for very long by other female members.</p>
<p>This style of communication is directly at odds with much of the harsh criticism and disdain found in predominantly male public comments, especially in most public online tech comment spaces, unfortunately.</p>
<p>Destructive criticism is the best way to keep a site predominantly male. It implies that there is no concern about whether a person can learn from a response or not, or whether they would find offense. It is an outward display of ego, a territorial &#8220;pissing rite&#8221; in which most women do not and will not participate. </p>
<p>That being said, there are many men who flock to women-only groups for the same reasons as women. They do not want to be subjected to the predominantly male style of communication where there is no sense of community, or even just simple accountability. They grow tired of the “pissing rite&#8221;, the absurd declarations of false boundaries, the outward display of insecurity through harsh criticism, implicit claims of “my way, my expertise, my right, never yours&#8221;, and poor display of ego. This mode of communication is an unproductive waste of time, and many men realize this as well. “I feel at home here because I really don&#8217;t want to deal with that male ego bullshit&#8221;, one male member of our political group stated to me. </p>
<p>Men who seek out women&#8217;s groups are usually welcome, or a splinter group is formed to accommodate these men, once it is determined that they do not seek membership for the wrong reasons. Some of the wrong reasons are:</p>
<p>(1) “I will be the only male member, and will therefore have my choice of &#8216;chicks&#8217;&#8221;. Nope. It&#8217;s not happening.<br />
(2) “I will be the only male member, and I&#8217;ll guide/help/protect these lost/vulnerable/endangered women&#8221;.  This is not only unnecessary, but laughable. Women find the implications of these assumptions both offensive and so primitive that it is hysterically funny.<br />
(3) “I will infiltrate because I hate women, and want to try to dissolve the group in some way&#8221; This is very rare, but happens. The good news is that the motives of both men and women who attempt this become very obvious very quickly. </p>
<p><strong><a name="6"></a>Women-only/women-friendly tech groups and gatherings offer a level of awareness of and accountability for behavior not found in most mixed gender tech groups/gatherings.</strong></p>
<p>Awareness of and accountability for behavior in women&#8217;s groups means a lot more than just safety from sexual harassment, or discrimination.  It means that if one is treated unfairly or harshly in any manner that a person finds offensive, the entire community will hear your claim. They will give you advice, opinions, and will collectively decide if action should be taken. </p>
<p>There has recently been a call for all public message board admins to get tougher about removing blatantly discriminatory, harassing, or sexually objectifying comments. This is a very necessary, damned good start. But to genuinely make an online tech community women-friendly, it needs even tighter moderation against <strong>harsh/demeaning criticism, elitist commentary, and exclusionist statements</strong>, the three most prevalent and women-unfriendly types of communication found in almost all moderated online tech message boards. There is no better way to give women a message that their comments are not welcome than implying that: (1) this is forbidden territory, women have no expertise here (2) your comments are stupid, wrong, or ridiculous, (3) we&#8217;re so much smarter than you.<br />
Discussion, constructive criticism, even heated debate happens in women-only groups, but these methods of communication are avoided. </p>
<p>Both online and off, I have seen men who communicate this way with everyone, and men who only choose to communicate this way with women. I have also seen this behavior tolerated or ignored for the most part. Here are my observations on why this happens. </p>
<p><strong><a name="7"></a>Men are generally very good at ignoring bad behavior.</strong></p>
<p>This is both a blessing and a curse. In my most recent office environment, we had situations where a male colleague&#8217;s behavior was abrasive in one of these three ways mentioned. &#8220;That sucks, doesn&#8217;t it?&#8221; I asked another male colleague. &#8220;Yeah, but I just ignore it. That&#8217;s just the way he is. He is always like that&#8221; He responded. This is what I&#8217;ve seen as the general male way of coping with this poor communication style.</p>
<p>It&#8217;s a blessing that many men can ignore it, in the sense that most men do not get caught up in deep analysis of why this person said a specific thing, and what this person could have really meant, etc. When almost everything is taken at face value, and not overanalyzed, the ability to ignore communication issues makes it is easier to resolve the simple issues, and move on. I have seen some women in office environments do the over analysis, and take offense when there never was one given. I don&#8217;t see men do this very often, and it makes communication quicker and easier. </p>
<p>Ignoring communication issues is also a curse because one obnoxious person is allowed complete freedom to make excessive noise, be rude and disruptive, or explicitly offensive. Most men, online or in the office, will ignore it. Most women will notice it but not say or do anything about it, for a variety of reasons which are tangential to this article. The offender often thrives on the fact that no one told them to stop, so they continue. Sometimes the offender is not socially adept enough to pick up on the fact that ignoring implies intolerance at some level. They somehow missed the message most three year olds learn: I&#8217;m ignoring you because I don&#8217;t like your behavior, so they continue the intolerable behavior.</p>
<p>This is so prevalent in online tech communities that it is the primary reason why many women do not participate. The poor communication and behavior of even one boorish, ego-driven, elitist, socially inept geek is just simply intolerable for most women. Women generally tend to assume that everyone will be conscious of and annoyed by this behavior. Men tend to assume that everyone will ignore it. This causes problems in offices as well as in online communities, where women will complain about such behavior, and men will issue responses such as “toughen-up&#8221;, or &#8220;what&#8217;s the big deal?&#8221; because this is how they cope with the problem. A female-friendly group addresses and tries to resolve these issues, while the average group ignores it until/unless the person does something heinous. </p>
<p><strong><a name="8"></a>The sense of community fosters a protective behavior within that community.</strong></p>
<p>If you do something awful to one woman in a women-only community, all will hear and know about it, and you are ousted. Most of the time this is first discussed and voted on by many group members. Many times the women&#8217;s group will even make an effort to explain the offense to the oblivious offender. But if the offender is still oblivious and/or offending, the offender is out. This is done to protect the interests and goals of the group. Many male dominated online groups don&#8217;t run this way. Most if not all women&#8217;s groups run this way, whether online or off. This relates to the awareness and accountability mentioned before. It&#8217;s an essential element of all women-only groups, and seems necessary for women-friendly groups to draw women. </p>
<p><strong><a name="9"></a>Women&#8217;s groups generally have a few vocal, and many silent, members</strong><br />
The vocal few express their opinions, and either gain support or do not gain support. The ones who gain support usually implicitly become the spokespeople for the silent many.<br />
The silent many usually let the vocal few, with whom they agree, do the job of ousting, protecting the sense of community, and publicly representing the silent many. The silent many support the vocal few. The community in turn supports and protects the rights and privileges of the silent many.</p>
<p>Why this happens is again a dynamic which is tangential to this article. But it seems that many women in group participation give either their silent support or rejection, speaking up only occasionally. Because of this behavior, if a communication problem arises in any type of group, whether women-only or not, and there is not a vocal few who will attempt to resolve it, the silent many will often silently leave. The silent many often don&#8217;t want to complain, for fear of having to deal with the additional frustration of the unaware/unconcerned “toughen-up&#8221;, or “what problem?&#8221; type of responses. For the silent many, it&#8217;s easier and less frustrating to just leave. I think it is important for groups that want to advertise themselves as being women-friendly, to be aware of this pattern. </p>
<p>One of the challenges of any women-only/women-friendly group is encouraging the silent many to speak up. Many women deal with demeaning and discriminatory behavior so often in their lives that they are too emotionally exhausted to deal with even the possibility of an online onslaught of anonymous discriminatory and demeaning comments. Many women spend time observing online groups before deciding if they will participate, for this very reason. They want to ensure that they will not feel verbally attacked once speaking up, and that their issues, comments and contributions will be heard and handled fairly.<br />
<strong><br />
<a name="10"></a>Women generally do not arm themselves for battle during tech discussions</strong></p>
<p>Women generally do not work things out through verbal battle. By the time they<br />
reach that point of wanting to argue, they are already so offended that they are in pure self-defense mode. Women treat the discussion of tech issues like the discussion of many other issues. It&#8217;s not competitive, and they wish to bi-directionally share information.</p>
<p>Many tech men envision a technical debate as a battle, and celebrate the supposed victory, exhibiting classic &#8220;Alpha Male&#8221; behavior. I have personally seen it so many times in my profession that I brace myself for it when discussing tech issues with new groups of men. So many of them arm themselves with weapons of aggression, demeaning comments, and behavior which encourage more of a filibuster than a healthy debate. The supposed tech discussion becomes a test of verbal and emotional endurance, where whomever can argue the hardest and last the longest wins. </p>
<p>They can shake hands afterwards and congratulate each other over a &#8220;good fight&#8221; after a technical debate. “I like the challenge of a good argument, which is why I do that&#8221; one male colleague explained to me. “I like a good technical debate too, but I don&#8217;t want to feel verbally or emotionally abused afterward. Women don&#8217;t fight for fun, they fight for personal issues.&#8221; I explained to my male colleague. </p>
<p>Unfortunately, the anonymity offered by many public wikis and message boards encourages the worst behavior in people. Even moderated tech chat areas and comment boards are rife with elitist, demeaning comments encouraging &#8220;the fight&#8221;. Some of it is due to oblivion, lack of knowledge that this is offensive to tech women. Some of it, unfortunately, is very intentional.</p>
<p>Apparently there are males online, in tech communities, who still believe that, like the cigar rooms of the Victorian Era, tech rooms should be male-only. Back then, the predominant purpose of smoking cigars in a common room was to have male-only space, and similarly today, the purpose of the demeaning and fight-provoking attempts is to maintain the male-only presence of some online tech spaces. I know for a fact this happens with intent in some online chat rooms and message boards. It is not simply an act of oblivion, but a concentrated, misogynistic effort between like-minded men to keep women out. </p>
<p>When I discuss this with people and we ask each other how this can be prevented, I feel overwhelmed. How do we stop any/all of the human behavior which prevents us from evolving further? I have no answer to this, but I am certain that if less of this behavior is tolerated online, we at least squeeze people who discriminate into their own, personal hidden online spaces. There is no reason why we need to be subjected to every single person&#8217;s beliefs or comments in the name of the First Amendment. We all have a right to remove from our lives anything and everything which holds us back in some way, even that which is subtly harmful or offensive. Web admins have a right to remove useless, demeaning, even subtly harmful comments in the best interest of an online community. The operative word here is “community&#8221;, and the appropriate questions is: Does your public comment space contribute to a community, or is it just an open toilet that everyone can vandalize and pollute?<br />
<strong><br />
<a name="11"></a>Did you know?</strong></p>
<p>When it was illegal for women to publish writing during various times in history throughout various countries, women published their work under male pseudonyms. <strong>Today, many tech women still use male pseudonyms</strong> when posting to lists or publishing tech articles. The reasons are to have their work read without bias, and to avoid misogynistic &#8220;hyper-scrutiny&#8221; of their work. I have experimented with this myself using a male pseudonym to post articles, and being told that the articles are informative, useful, great. Six months later I republish the exact same article, using a different title and a female pseudonym, and suddenly the article is horrible, technically incorrect, useless. It&#8217;s a fascinating study. I would love to see some prominent male techs publish under female pseudonyms, and watch the responses. </p>
<p>Women find it awkward to brag about their writing accomplishments published under male pseudonyms. For this reason, most of this work never gets credited to the correct person, and is never acknowledged on resumes or during job interviews. “How do I explain to a male &#8216;potential boss&#8217; why I have chosen to use a male pseudonym, without bringing up the whole discrimination issue?&#8221; is what one female tech friend asked me. I had no answer for her. I have also let my work published under male pseudonyms fall between the cracks, into oblivion, not knowing what else to do. </p>
<p><strong><a name="12"></a>To make an online community more women-friendly, try these suggestions:</strong></p>
<p>(1) Monitor the public comments. Treat the public comments interface much like the<br />
front door to your home. You don&#8217;t simply leave it open for any idiot to waltz in.<br />
You can be selective regarding who comes in, and what they do once they&#8217;re in.</p>
<p>Useless comments get deleted as quickly as they appear. Any non-technical,<br />
offensive, destructive, or off-topic comment is removed. This gives a clear<br />
message about will and will not be tolerated. As useful comments accumulate,<br />
useless ones are much less likely to appear.</p>
<p>(2) The technically correct but aggressive/demeaning/overly harsh comment gets returned<br />
to the sender, asking the person to re-word using constructive criticism.<br />
Sounds like overkill, but it&#8217;s not. The &#8220;You&#8217;re wrong, here&#8217;s the right answer&#8221;<br />
type of response constitutes picking a battle that most women won&#8217;t fight, or won&#8217;t even bother dealing with. </p>
<p>(3) Treat your online space like a community. The web admin should act is if they&#8217;re on the board of chosen freeholders, voting on issues which affect themselves and the entire community. Don&#8217;t just throw up the comment space and leave it abandoned for vandals and other jerks. Maintain it according to the rules by which you want everyone to abide, and stick by your decisions. Have accountability for comments. Create a space where open discussion happens as if it were in an educational surrounding, not a seedy bar.</p>
<p>(4) Explicitly state that your site is women-friendly. Doing this will encourage the silent many to speak up. Kick out the jerks who don&#8217;t want your online space to take this direction. </p>
<p><strong><a name="13"></a>For the men who care: Tips for communicating with women in Tech environments, online and Face-to-Face</strong></p>
<p>(1) Tech women usually express great enthusiasm about their work. They do what they love, and they love what they do. When a woman gets enthusiastic about her work and shares that enthusiasm with you, <strong>it has absolutely nothing to do with you, or sex</strong>. I cannot tell you how often I have seen this. Some men mix up their incoming signals, and a women&#8217;s enthusiasm at work somehow translates to someone flirting with them at a bar. I have no idea how this happens, but it&#8217;s profoundly sad to see it happen again and again. If you&#8217;re lacking something in your life, please do not look to your female tech colleague to fill that niche. Do not even presume her mind is there even if yours is not, because hers is not, and your signal indicator needs serious recalibration. </p>
<p>(2) Leave your libido at the door. Please. Women tech colleagues want to be appreciated for their brains, their technical expertise, their contributions and accomplishments. <strong>Tech women do not give a flying shit about what their male colleagues think of their attire, their make-up or their body parts</strong>. Believe me when I say this is true. Women may give you a polite response, but on the inside they are offended, seething, and considering whether or not to go to their attorney. They will ask other women in the office or field if they too suffer from this problem, building an alliance against men in their company who do this. And soon you will have a legal problem. Leave it at the door, pick it up on your way out. No one else wants it. </p>
<p>(3) Some tech women dress up for work. <strong>It is NEVER for you</strong>. Many tech women wear clothing which makes them feel good. For some, comfort is paramount, if for example the tech female is crawling through the ceiling, moving dusty panels and running CAT5 cable. For other tech women who would not get their clothes ruined at work, they like to dress up. “It makes me feel confident. I look at myself in the mirror and I feel good.&#8221; my female colleague told me. For tech women at work, feeling “good&#8221; does not mean “sexy&#8221;, and it is not for you at all. It is entirely about self-confidence, self-encouragement, and giving one&#8217;s self the extra strength to prove they know their stuff in a technical environment. Note the emphasis on &#8220;self&#8221;: it is entirely for her, by her, and your reaction is entirely irrelevant. </p>
<p>I have heard males say horrible things in professional environments like &#8220;Well, you wore that dress, you do look great in it, that must be the reaction you wanted. Isn&#8217;t that why you wear that dress?&#8221; The answer is no, fool, get over yourself.</p>
<p>(4) Tech women are generally open-minded about what is commonly called &#8220;guy humor&#8221; and &#8220;guy socialization&#8221;. Guaranteed, many of them, myself included, have male friends with which they hang out on a regular basis, so this is far from a foreign concept to tech women. Chances are, the tech women of your group would enjoy your jokes and would like to be invited out for beers, as long as points (1) through (3) above are met. I personally enjoy and share many of my own raunchy or lewd jokes if I feel safe around the people with whom I&#8217;m joking. I enjoy hanging out afterwards over a beer or two, or going out late with &#8220;the guys&#8221; to a bar to welcome the &#8220;new guy&#8221;. These things could be fun for everyone if (1) through (3) are in order. </p>
<p>(5) To the men who do not do any of this: Thank you so much. We notice, and greatly appreciate this. I have been fortunate to work with some excellent men in tech, and I wanted to thank you and the many others for not being this way. </p>
<p>(6) No, women are not perfect. This article doesn&#8217;t imply or suggest that women are close to prefect and men are far from it. I know there are female stereotypes not mentioned in this article, mostly because I personally don&#8217;t find them in tech environments. Your experience may vary. All of these points can be applied to both genders. But the fact that I was asked by several different sources to write this article proves that there is a recognized gender divide in many tech spaces. All of what I have posted is what I and others have observed and experienced. None of it is fiction. </p>
<p>(7) Is someone making you feel uncomfortable? Speak up! If someone at work makes you feel uncomfortable, tell them so. If you feel discomfort coming from another person, and you think you&#8217;ve caused it inadvertently, say so. Make it clear and shove it out of the way as quickly as you can, so work can continue. This applies from/to men and women. </p>
<p>(8) But isn&#8217;t creating a women-only group, and using terms like &#8216;male behavior&#8217; reverse sexism? Doesn&#8217;t this defeat the very goal you wish to achieve? My response is no, not if these tools/verbiage are used to try to ultimately achieve equality. If it&#8217;s used for mudslinging, or through some act of elitist exclusion, yes, it is reverse sexism. </p>
<p>Credits: Many thank yous to Carla Schroder for sharing her infinite wisdom and encouragement. A huge thank you to all of the women at LinuxChix.org for your tireless support of the cause over the years. Thank you to DevChix.com for giving my wayward articles a very worthy home. Thank you to the many readers who have left constructive criticism and comments. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/06/09/let%e2%80%99s-all-evolve-past-this-the-barriers-women-face-in-tech-communities/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: Beginning Ruby On Rails E-Commerce</title>
		<link>http://www.devchix.com/2007/05/12/book-review-beginning-ruby-on-rails-e-commerce/</link>
		<comments>http://www.devchix.com/2007/05/12/book-review-beginning-ruby-on-rails-e-commerce/#comments</comments>
		<pubDate>Sat, 12 May 2007 16:33:38 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/05/12/book-review-beginning-ruby-on-rails-e-commerce/</guid>
		<description><![CDATA[Beginning Ruby On Rails E-Commerce
From Novice to Professional
by Christian Hellsten and Jarkko Laine
published by: Apress
Book Site &#124; Sample Chapter &#124; Table of Contents
I got this book to review and set it on the shelf for a few months&#8230; by the time I got to it Rails was up til version 1.2 and this seems to [...]]]></description>
			<content:encoded><![CDATA[<p>Beginning Ruby On Rails E-Commerce<br />
From Novice to Professional<br />
by Christian Hellsten and Jarkko Laine<br />
published by: Apress</p>
<p><a href="http://apress.com/book/bookDisplay.html?bID=10178">Book Site</a> | <a href="http://apress.com/book/supplementDownload.html?bID=10178&#038;sID=3926">Sample Chapter</a> | <a href="http://apress.com/book/supplementDownload.html?bID=10178&#038;sID=3925">Table of Contents</a></p>
<p>I got this book to review and set it on the shelf for a few months&#8230; by the time I got to it Rails was up til version 1.2 and this seems to be written for version 1.1.2 Ã¢â‚¬â€œ DOH! I tried a few examples and wasn&#8217;t compiling. After a little investigation there are only a few differences that would hinder this book from working with Rails 1.2. Namely, the assert_select has replaced assert_tag. That being said, this book is still great and applicable to Rails today. If you think about it, with as fast as Rails as grown it is impossible to keep 100% up to date! </p>
<p>This book is totally fantastic for beginners Ã¢â‚¬â€œ because it actually shows Test Driven Development. What you say? Most books say something like that Ã¢â‚¬Å“to keep code size down, tests and error checking have been left for an exercise to the readerÃ¢â‚¬Â &#8230; Riiiiiiiiiiight. How are you going to teach people coding that way? Tests should just be an automatic task of a programmer. Write some test&#8230; write some code. I honestly can&#8217;t imagine anymore how you could code anyways without them! </p>
<p>Not only does this book cover testing (including acceptance testing with selenium in later chapters Ã¢â‚¬â€œ whoo hoo!) it starts out with not using scaffolding. I think, and this happened to me, at first I used scaffolding for everything and didn&#8217;t really understand the process. The book first goes through the Ã¢â‚¬Å“scaffold processÃ¢â‚¬Â by hand, writing each method and view Ã¢â‚¬â€œ after writing the test. Very cool. Then it tells you how to use scaffolding for the next model in the sample application. Awesome.</p>
<p>It talks about common concepts for really any site Ã¢â‚¬â€œ tagging, adding forum, adding a form to upload images, browsing a list of products, multiple language support. Even if you are not selling anything on your site, you will still find this book extremely helpful.</p>
<p>Impress your friends! Learn how to write a DSL for testing. This is cool stuff, DSLs fascinate me to no end. Any and all mentions of it I study intently. Rails is in a way, a DSL for web applications! </p>
<p>Being true to the title Ã¢â‚¬Å“e-commerceÃ¢â‚¬Â it actually talks about how to do payments over the web. Most books who talk about shopping carts skip that important step! </p>
<p>When you are ready to make your millions on the web there is quite an extensive chapter on deploying your site. It talks about LightTPD, capastrano, caching, and security! Its really nice to have all this in a book, instead of constantly looking online for documentation</p>
<p>My only complaint is Ã¢â‚¬â€œ it doesn&#8217;t specifically mention what version of rails it used, I assume from the output of script/about that is 1.1.2 &#8230; and they should of talked about how to check out a particular version of Rails, just in case you wanted to use the exact version that is used in the book. Which may not be a bad idea for new users.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/05/12/book-review-beginning-ruby-on-rails-e-commerce/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: Pro PHP Security</title>
		<link>http://www.devchix.com/2007/02/25/book-review-pro-php-security/</link>
		<comments>http://www.devchix.com/2007/02/25/book-review-pro-php-security/#comments</comments>
		<pubDate>Mon, 26 Feb 2007 04:27:14 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/02/25/book-review-pro-php-security/</guid>
		<description><![CDATA[ProPHP Security
Published by: Apress
Authors: Chris Snyder and Michael Southwell
Book Site &#124; Sample Chapter: Preventing SQL Injection &#124; Table of Contents
At first, I thought this book was all about cleaning your input variables and filtering your output, XSS attacks, SQL injections but I was most presently surprised to find that it was that and so much [...]]]></description>
			<content:encoded><![CDATA[<h2>ProPHP Security</h2>
<p>Published by: Apress</p>
<p>Authors: Chris Snyder and Michael Southwell</p>
<p><a target="_blank" href="http://apress.com/book/bookDisplay.html?bID=437">Book Site</a> | <a target="_blank" href="http://apress.com/book/supplementDownload.html?bID=437&#038;sID=2957">Sample Chapter: Preventing SQL Injection</a> | <a target="_blank" href="http://apress.com/book/supplementDownload.html?bID=437&#038;sID=2955">Table of Contents</a></p>
<p>At first, I thought this book was all about cleaning your input variables and filtering your output, XSS attacks, SQL injections but I was most presently surprised to find that it was that and so much more! In fact, I would have called this &#8220;ProPHP Security and Administration&#8221; instead! It is absolutely fantastic. It really is about security in all of the facets of web development - from server, to code, to database to the system users.</p>
<p>The book is divided into 4 parts:</p>
<ul>
<li>Part 1: The Importance of Security</li>
<li>Part 2: Maintaining a Secure Environment</li>
<li>Part 3: Practicing Secure PHP Programming</li>
<li>Part 4: Practicing Secure Operations</li>
</ul>
<p>Here are some brief overviews of the sections and the tidbits I found interesting:</p>
<p><strong>Part 1:</strong></p>
<p>The first part is the shortest and gives a general overview the what and why of security.</p>
<p><strong>Part 2:</strong></p>
<p>The second is much more hearty and goes into detail about Shared hosts and why they are secure and how to make the more so. It even dips into alternatives for the traditional shared hosts and goes into Virtual Machines. This is valuable to not only to administrators but to PHP Developers. After reading this, I understand the &#8220;why&#8221; behind many of the things about shared hosting that I found frustrating.</p>
<p>One of the most important things I found in this chapter is how to maintain separate development and production environments. When I was helping to set this up at one of my past jobs it was a topic that I couldn&#8217;t find much information about. It also makes mention of version control, using wikis, bug tracking, sandbox and testing! Oh and here&#8217;s a conceptÃ¢â‚¬Â¦. pretend your live system failed &#8212; how well does your backup plan work?</p>
<p>How many times have I thought, I should make a cron job to back up my database to my home server every day/week? Have I ever done this? No! But now I have no excuse! Backing up a database and storing remotely is one of the sections in this chapter and code included! Fantastic.</p>
<p>There are chapters about Encryption theory and practice which I read several times to understand. It was interesting but it wasn&#8217;t something I have to do right now in my life, but I will return to this book to refresh my memory when I do.</p>
<p>Securing Network connections SSL and SSH, these proved helpful as I have become the &#8220;Reluctant System Admin&#8221; for one of my projects &#8212; partly because if they were to hire a part time person I&#8217;d rather they get a CSS person and I&#8217;d rather do the sys admin!</p>
<p>The Controlling Access section goes into details about using certificates with php, single sign-on, basic and digest http authentication Ã¢â‚¬Â¦ whoa this is some deep stuff! But good, when I was looking into this for a project a few years ago I couldn&#8217;t find anything helpful. It continues with then permissions and restrictions, a lot about Unix permissions and keeping things running where they should, securing databases and PHP Safe mode!</p>
<p><strong>Part 3</strong></p>
<p>Finally &#8212; the stuff that I thought the book would be about - validating user input, filtering output, preventing cross site scripting attempts, remote execution.. so much more to security than I thought! It talks about securing temp files, I always assumed the OS handled this and I didn&#8217;t need to worry.</p>
<p><strong>Part 4</strong></p>
<p>Ahh &#8212; Practicing Secure OperationsÃ¢â‚¬Â¦ all you ever wanted to know about making sure your users are humans, verifying your users, setting roles for users, logging your users actions, preventing data loss, executing system commands safely, working with webservices and finally Peer Reviews! Sometimes it&#8217;s that extra pair of eyes that can see things you miss.</p>
<p>Something I find interesting - in the section about preventing data loss, it talks about setting a flag on records that are &#8220;deleted&#8221; and then making a db view of the &#8220;good&#8221; data  and using that to select from. One of the things I like in Ruby On Rails is this &#8220;acts_as_paranoid&#8221; model option that does about the same thing. Neato.</p>
<p>Pro PHP Security is a most excellent read and so much deeper than my brief overview here. It will be a handy book on my shelf to keep me on my toes regarding security in all areas of web development, from the server to the code, to the users, to best practices of security you will find this is a helpful book too!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/02/25/book-review-pro-php-security/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review: Beginning Ajax with PHP by Lee Babin</title>
		<link>http://www.devchix.com/2006/12/13/book-review-beginning-ajax-with-php-by-lee-babin/</link>
		<comments>http://www.devchix.com/2006/12/13/book-review-beginning-ajax-with-php-by-lee-babin/#comments</comments>
		<pubDate>Wed, 13 Dec 2006 14:26:54 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Javascript/AJAX]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=18</guid>
		<description><![CDATA[Book Review
Beginning Ajax with PHP by Lee Babin, published by Apress
Book Site &#124; Sample Chapter: 3 PHP and Ajax &#124; Table of Contents
Although no stranger to Ajax, I received a review copy of Beginning Ajax with PHP expecting some watered down presentation of Javascript with some PHP thrown in. I was quite surprised to find [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">Book Review<br />
Beginning Ajax with PHP by Lee Babin, published by Apress</p>
<p class="MsoNormal"><a href="http://apress.com/book/bookDisplay.html?bID=10117">Book Site</a> | <a href="http://apress.com/book/supplementDownload.html?bID=10117&#038;sID=3896">Sample Chapter: 3 </a><a href="http://apress.com/book/supplementDownload.html?bID=10117&#038;sID=3896">PHP and Ajax</a> | <a href="http://apress.com/book/supplementDownload.html?bID=10117&#038;sID=3897">Table of Contents</a></p>
<p class="MsoNormal">Although no stranger to Ajax, I received a review copy of <em>Beginning Ajax with PHP</em> expecting some watered down presentation of Javascript with some PHP thrown in. I was quite surprised to find a good presentation of using Ajax and PHP, easy enough for the beginner and still interesting for those who have done it for years.</p>
<p class="MsoNormal">
<p class="MsoNormal">The book starts out exactly how I would write it &#8212; SIMPLE! The first time I did Ajax with XHR (xml http request), I used a plain text file, which I then read into a DIV at the click of a link. This takes a similar approach and has data stored in an array which is then accessed with a simple call to a PHP file. The following chapter, takes it a step further and this building upon previous chapters is a common theme in the book.</p>
<p class="MsoNormal">
<p class="MsoNormal">After going through the basics, the book gets into more practical uses of Ajax. The latter chapters talk about using forms to pass along data to be processed by Ajax and doing form validation. It also gives a good explanation of the proper use of the form methods GET and POST. It goes into detail about uploading images and other files using a hidden form submit trick, since XHR doesn&#8217;t support file uploading (javascript is not allowed to access files on your harddrive). And this chapter is the perfect predecessor to the &#8220;Real-World Ajax Application&#8221; chapter where you will take what you have learned and create an Ajax based photo gallery. Practical, hand-on is the best way to learn something IMHO (Sorry &#8220;Hello World&#8221; scripts!). It is interesting that this chapter is in the middle of the book, when I would expect it at the end. Perhaps the author wanted the user to jump in and try it, instead of persevering to the end. I don&#8217;t know about you, but often the last few chapters of the book go unread by me.</p>
<p class="MsoNormal">
<p class="MsoNormal">After the reader has confidence on how to use AJAX, the book gives the warning, Ã¢â‚¬Å“Whoa! Wait a minute! AJAX isn&#8217;t appropriate for EVERYTHING!Ã¢â‚¬Â It gives examples of when AJAX would be a good idea and when it would not. I think this is pretty important as each CEO now wants Ajax everywhere in their application but it&#8217;s not always the best solution! And it talks about the classic, Ã¢â‚¬Å“THE BACK BUTTONÃ¢â‚¬Â, problem. Then, in the same chapter, the book takes sort of a funny turn (in my opinion) and gives an introduction to PEAR.  The book explains how to use PEAR&#8217;s HTML_TABLE class to illustrate a good use for Ajax in creating an Excel-like grid that sums columns. This is a very cool class but would have been better suited for an appendix.</p>
<p class="MsoNormal">
<p class="MsoNormal">The rest of the book seems to be a random splattering of interesting topics: web services, map applications, cross-browser issues (touches again on the back button problem - but a solution this time!). There is also a brief mention of security. This should have been more in the middle of the book (see above for skipped last chapters syndrome). What then follows is a testing and debugging chapter which would have been more effective as the 3 or 4th chapter in the book. Finally there is a chapter about the browser DOM.</p>
<p class="MsoNormal">
<p class="MsoNormal">A great minor addition to the book would be an overview of some Ajax libraries such as Prototype, JQuery, Dojo, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2006/12/13/book-review-beginning-ajax-with-php-by-lee-babin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New Book: Mongrel by Angel Dobbs-Sciortino</title>
		<link>http://www.devchix.com/2006/11/21/mongrel-book/</link>
		<comments>http://www.devchix.com/2006/11/21/mongrel-book/#comments</comments>
		<pubDate>Tue, 21 Nov 2006 20:41:06 +0000</pubDate>
		<dc:creator>Angel N. Sciortino</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Languages]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=16</guid>
		<description><![CDATA[My book on Mongrel published with O&#8217;Reilly is now available for purchase.  Mongrel is a web application for Ruby on Rails, more stable than WEBrick, and easier to set up than FCGI to Rails through Apache.  You can find it at http://www.oreilly.com/catalog/mongrelpdf/.
]]></description>
			<content:encoded><![CDATA[<p>My book on Mongrel published with O&#8217;Reilly is now available for purchase.  Mongrel is a web application for Ruby on Rails, more stable than WEBrick, and easier to set up than FCGI to Rails through Apache.  You can find it at <a href="http://www.oreilly.com/catalog/mongrelpdf/">http://www.oreilly.com/catalog/mongrelpdf/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2006/11/21/mongrel-book/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
