Friday, December 22, 2006

Wii Browser

Nintendo released a demo of their browser for the Wii. It seems to work pretty well for checking the weather, email, google. I tried a few of the kids sites like NickJr, but it only played some of the flash content. The videos didn't work since they were windows media. Since I can now check Weather.com using the browser, I doubt I would use their Forcast Channel.

If you have a Wii, try WiiCade which has some good games optimized for the Wii. There are also some wii flash games at Albino Black Sheep Wii Games; but I havent tried them so I cant comment on the quality of the games at Albino. WiiCade had certainly done a good job making a Wii optimized page, and providing good games.


Enjoy!

Friday, September 29, 2006

RSS feeds from Ruby

A friend asked me if I knew a good way to create RSS feeds. He want RSS feeds created for some web sites that didn't already have them. My favorit answer: Ruby.

So I created a demo script in Ruby that parses Fatwallet.com and creates an RSS feed for topics that are rated "Better" or higher. The hardest part of this problem was parsing the HTML, but Ruby made that pretty easy. Creating the RSS information was very simple.

The code below has plenty of comments because my friend doesn't know Ruby. His background is more .Net, Java, and Perl.

#  This is a simple example.  It reads the Hot Topics forum
# on Fatwallet.com finding all topics rated "Better" or higher.
# It will print these topics and their URL as it finds them.
# Finally, it prints the RSS feed for this information.
# See: http://www.fatwallet.com/c/18/
#
# Three steps to run this script...
#
# You can get Ruby from http://www.ruby-lang.org/en/downloads/
# I highly recommend the One-click Installer for Windows
#
# This program uses an extra library, Hpricot, to parse HTML.
# To get Hpricot installed, use Ruby's package manager "Gems"
# Just run the follow at your DOS cmd prompt
# gem install hpricot
#
# To run the program from the DOS cmd prompt...
# ruby RubyBot-forRich.rb
#
# RSS feed creation using the RSS library for Ruby
# see: http://www.ruby-doc.org/stdlib/libdoc/rss/rdoc/index.html
# tutorial: http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en

# "require" is not like "using" in C# nor "#include" in C++.
# require searches the library for the correct ruby file and executes it.
require 'rubygems'
require 'open-uri'
require 'rss/maker'
begin
require 'hpricot'
rescue LoadError # this is like a Try Catch, but there are nifty differences
puts 'Please run "gem install hpricot" before running this program.'
exit
end

BETTER = 4 # a constant

doc = Hpricot(open('http://www.fatwallet.com/c/18/'))

rss = RSS::Maker.make("1.0") { |maker|
#
# Let me explain what is happening...
# The ".make" method created a Maker object, passed it into
# the block (i.e. everything between { and }) as the variable 'maker'.
# Executed the block. Then ".make" returns the RSS object that
# was built while executing the block.
#
maker.channel.about = 'http://www.fatwallet.com/c/18/'
maker.channel.title = 'Fatwallet.com Hot Deals Forum'
maker.channel.description = 'Hot deals rated "Better" or higher.'
maker.channel.link = 'http://www.fatwallet.com/c/18/'

puts 'Searching...' # puts is similar to WriteLine in .Net

(doc/'tr').each { | tr |
#
# (doc/'tr') => performed an XPath search on doc and got a collection of <tr> nodes
# .each => iterates over the collection passing elements one at a time to the "{ |tr| ... }" block
# { | tr | ... } => this is a Closure, the variable 'tr' gets set to the element passed in
#
# similar to C#...
# foreach( Node tr in doc.FindAllNodes( 'tr' ) ) { ... }
# but not really since it is using a closure.
#
# I had to loop on <TR> html tags because I will need to reference this tag later.
#
(tr/'td/img[@title]').each { |img|
if img['title'] =~ /rating: (\d+)/
# $1 is the first group from the match, the rating number
if $1.to_i >= BETTER
(tr/'a[@href]').each { | a |
if a['href'] =~ /^\/t\/18/
puts "http://fatwallet.com#{a['href']} #{a.inner_html}"

item = maker.items.new_item
item.link = "http://fatwallet.com#{a['href']}"
item.title = a.inner_html

end
} # each a
end # if rating >= better
end # if title is rating
} # each img
} # each tr
} # RSS maker

puts "\nRSS..."
puts rss

Long time no post... why?

Two months and nothing posted. The reason is my wife is pregnant with our third child. Just like the first two, the pregnancy is very difficult. So I haven't done much blogging nor extra coding.

Saturday, July 22, 2006

Let ActiveRecord support Enterprise Databases.

I am currently investigating using ActiveRecord's Migrations to support a legacy enterprise application. Migrations could help us because we currently support multiple versions of the product, which means multiple versions of the schema. Development and QA are already spending too much time reinstalling different versions of the database.

So can ActiveRecord Migrations support my application? Nope; not right out of the box.

Can I tweak ActiveRecord to support my application? YES! It isn't too hard to extend/override ActiveRecord.

Why can't ActiveRecord support my application out of the box? The short answer is ActiveRecord was written to only support a database neutral schema. Supporting multiple databases means only supporting the lowest common denominator. So db specific types in my schema like tinyint and smallint get simplified to integer. ActiveRecord doesn't support all the different constraints that are available: foreign keys, composite keys, triggers. Also, I noticed ActiveRecord did not capture any of my Views (SqlServer).

In addition, I have a deployment problem. I have to ship and deploy my application to customers. Right now, I can't ship and install Ruby on those machines. So I'd rather just have ActiveRecord Migrations produce a SQL file that I can deploy.

After a little experimentation, I discovered it is possible to easily overcome these issues. The first is can I run Migrations without Rails? This is easily accomplished as described on PragDave's blog.

Next, I wanted to know how I could modify ActiveRecord to serve my needs. Thankfully Ruby is such a flexible language that it allows modification of existing classes. So I can override ActiveRecord methods as needed. For example:

require 'rubygems'
require 'active_record'

module ActiveRecord
module ConnectionAdapters # :nodoc:
class SQLServerAdapter
def execute( sql, name = nil )
puts sql
puts "GO"
puts
end
end
end
end



In the example above, I first load ActiveRecord, then modify the SQLServerAdapter's execute method (my database is SqlServer). It turns out that this method is called by Migration to send SQL to the database. So in this example, I am simply sending the SQL to STDOUT. Notice that I can also modify the output. In this example I add the “GO” command between SQL statements. I could have just as easily added transactions or error checking. With a few more tweaks, I could have sent this to a file to generate a SQL script from the Migration.

ActiveRecord contains code to simplify data types for database neutrality. Since the legacy database uses many other types, this simplification is an issue. So after examining the source, I found a couple of places where the simplification is applied. By overriding these methods it is easy to get all ActiveRecord to support the data types required. For example, the code below adds several types.

module ActiveRecord
module ConnectionAdapters # :nodoc:
class SQLServerAdapter
def native_database_types
SQLServerAdapter.native_database_types
end

def self.native_database_types
{
:binary => { :name => "binary", :haslimit => true },
:bit => { :name => "bit"},
:char => { :name => "char", :haslimit => true },
:decimal => { :name => "decimal" },
:int => { :name => "int" },
:nvarchar => { :name => "nvarchar" },
:real => { :name => "real" },
:smallint => { :name => "smallint" },
:tinyint => { :name => "tinyint" },
:timestamp => { :name => "timestamp" },
:uniqueidentifier => { :name => "uniqueidentifier" },
:varchar => { :name => "varchar", :limit => 255, :haslimit => true },
:primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY",
:text => { :name => "text" },
:float => { :name => "float", :limit => 8 },
:datetime => { :name => "datetime" },
:image => { :name => "image"},
}
end
end

class ColumnWithIdentity
def initialize(name, default, sql_type = nil, is_identity = false, null = true, scale_value = 0)
super(name, default, sql_type, null)
@identity = is_identity
@is_special = sql_type =~ /text|ntext|image/i ? true : false
@scale = scale_value
# SQL Server only supports limits on a few types
@limit = nil unless SQLServerAdapter.native_database_types[@type][:haslimit] == true
end


#DO NOT SIMPLIFY, Just use the native type name; trim off size
def simplified_type(field_type)
field_type.slice( /[^\(]*/).to_sym
end
end
end
end



This example shows how easy it is to change ActiveRecord's behavior as needed.

Now the code above isn't a complete solution, but it will get SchemaDump to output the correct types that my legacy system is using. If you look at the original methods you can see the changes were pretty simple to make. One refactoring I did was to make SQLServerAdapter's instance method native_database_types into a class method. Then I could access it from ColumnWithIdentity, where it was copied code before. Also, I added the :haslimit key to make the code in ColumnWithIdentity more data driven off the native_database_types hash. Before, it had the types with limits hard coded into the ColumnWithIdentity initialize method.

What about adding new features? This is probably the easiest of all. A frequent request is to support composite keys. Just as an example of extending the DSL, the following will create a primary key constraint and support multiple columns in the key.

module ActiveRecord
module ConnectionAdapters # :nodoc:
module SchemaStatements
def add_pk(table_name, column_names)
quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
sql = "ALTER TABLE #{table_name} ADD CONSTRAINT PK_#{table_name} PRIMARY KEY CLUSTERED ( #{quoted_column_names} ) ON [PRIMARY]"
execute(sql)
end
end
end
end



This is simple DSL programming in Ruby. Another approach is to allow the :primarykey option for the create_table method to take an array of column names. I'll leave that exercise for later.

These examples show what is possible. I know there is a raging debate about supporting db neutrality verses db specifics. DHH has expressed his intention to keep Rails db neutral, because that is best for the world he lives within. For those of us unfortunate enough to live with legacy databases, we need an ActiveRecord that fully supports our database. Why not support both? Why not setup a method for the enterprise folks to add the database specifics to ActiveRecord? Maybe some form of plug-in or stable API that we could extend (my changes above risk being broken by future versions of ActiveRecord). To satisfy the db neutral camp, just generate warnings or errors if db specific extensions are used when ActiveRecord is configured to be db neutral.

Happy Migrating!

Friday, June 30, 2006

Thursday, June 22, 2006

Ruby: Meta Programming and Stack Traces

A couple of times I have run into trouble debugging or tracing a method in Ruby. Usually you can just call Kernal.caller to get a stack trace. But what if the method was generated? You don't get the correct location. For example:

class Kung
mstr = %-
def foo
puts 'Hello World from Kung.foo'
puts caller(0)
end
-
module_eval mstr
end

Kung.new.foo


Which generates the following output:

Hello World from Kung.foo
(eval):4:in `foo'
Kung-foo.rb:11


The stack trace only shows "(Eval):4:in 'foo'" which is almost useless. The "(Eval)" is a clue that the method was dynamically created using meta-programming. In this simple example, it is easy to find the dynamic code since it is near the caller "Kung-foo.rb:11". However in a real project it is frequently located far away, possibly in other source files.

To fix the stack trace, the author should use the optional arguments to method_eval as follows:

class Monkey
line, mstr = __LINE__, %-
def see
puts 'Hello World from Monkey.see'
puts caller(0)
end
-
module_eval mstr, __FILE__, line
end

Monkey.new.see


The output now shows the correct line number and file name:

Hello World from Monkey.see
Monkey-see.rb:5:in `see'
Monkey-see.rb:11


Update after reading the code in ActiveSupport core_ext\attribute_accessors.rb I found a nice way to do the above with fewer lines of code:

class Monkey
module_eval(<<-EOS, __FILE__, __LINE__)
def see
puts 'Hello World from Monkey.see'
puts caller(0)
end
EOS
end

Monkey.new.see

Monday, June 19, 2006

Ruby Class Variables, Attributes and Constants

Ruby Class Variables, Attributes and Constants

(For a related post, see Use Class Instance Variables Not Class Variables)


Writing a little ruby code the other day, I wanted to use a class variables but it didn't behave as expected.


01: class Class_Variable
02: @@var = 1
03: def Class_Variable.report; @@var end
04: end
05:
06: class Child_V < Class_Variable
07: @@var = 2
08: end
09:
10: puts Class_Variable.report #=> 2
11: puts Child_V.report #=> 2
12:


I was surprised by the result. Most other languages would have the child class shadow the parent field, but Ruby shared it! Ruby does provide Class Attributes and Constants as alternatives, but each has it's own symantics.

I threw together the following code to show the differences.


01: class Class_Variable
02: @@var = 1
03: def Class_Variable.report; @@var end
04: end
05:
06: class Child_V < Class_Variable
07: @@var = 2
08: end
09:
10: puts Class_Variable.report #=> 2
11: puts Child_V.report #=> 2
12:
13:
14:
15: class Class_Attribute
16: @var = 1 #class attribute
17:
18: def initialize
19: @var = 2 #instance attribute
20: end
21:
22: def report
23: @var # instance attribute, not the class attribute
24: end
25:
26: def Class_Attribute.report
27: @var # class attribute
28: end
29: end
30:
31: class Child_A < Class_Attribute
32: @var = 3
33: end
34:
35: puts Class_Attribute.report #=> 1
36: puts Class_Attribute.new.report #=> 2
37: puts Child_A.report #=> 3
38: puts Child_A.new.report #=> 2
39:
40:
41:
42: class Class_Constant
43: VAR = [ 'a' ]
44: VAR2 = [ 'b' ]
45:
46: def self.report
47: VAR2[0]
48: end
49: end
50:
51: class Child_C < Class_Constant
52: VAR2 = [ 'c' ]
53: end
54:
55: puts Class_Constant::VAR[0] #=> 'a'
56: puts Class_Constant::VAR2[0] #=> 'b'
57: puts Class_Constant.report #=> 'b'
58: #puts Child_C::VAR[0] #=> uninitialized constant error
59: puts Child_C::VAR2[0] #=> 'c'
60: puts Child_C.report #=> 'b'
61:


First notice that Class Variables are shared with their subclass (lines 1-11) . This differs greatly from Java and C# which shadow inherited variables.

The Class Attributes and Constants are "class private". That is, the child has no access to the parent attribute/constant with the same name. Class methods however are inherited. So calling "report" for Child_A and Child_C displays a significant difference between using Class Attributes and Constants (lines 37 and 60).

Unfortunately none of these alternatives matches the behavior seen in other languages. This can cause some confusion when going from Java or C# to Ruby. Class Attributes using accessor methods is the closest match to other languages. However the syntax similarities between class attributes and instance attributes can cause problems (lines 16, 19, 23, 27).

Tuesday, June 06, 2006

Wednesday, May 24, 2006

attr_accessor meta programming

Reading Jamis Buck's article Writing Domain Specific Languages I decided to attempt his challenge to write my own attr_accessor function.

First, I was curious to see how attr_accessor was implemented in Ruby. I found the source in object.c which simply calls "rb_attr(klass, rb_to_id(argv[i]), 1, 1, Qtrue);". The "rb_attr" function is located in eval.c. If you spend a few min looking at it, you will see it has special code for handling Access Control (public, private, protected). For now, I will ignore Access Control, and just implement creating the accessor methods.

Where should attr_accessor go? Looking at the docs, you will find attr_accessor is a member of Module. To see if I had the correct location, I quickly wrote...

module Module
alias old_attr_accessor attr_accessor

def attr_accessor( *symbols )
puts "attr_accessor called with #{symbols.join(' ')}."
old_attr_accessor( *symbols )
end
end


This failed since Module is not a module, it is a class! Laughing at myself and Ruby, I corrected the definition. The code above also demonstrates how easy you can implement simple Aspect Oriented Programming in Ruby. Using alias, I give the old attr_accessor method an new name old_attr_accessor. Then overwrite attr_accessor with my own code. Any call to attr_accessor will now print out the information that it was called.

Fun so far, but I haven't really defined my own version of attr_accessor. I've simple called the old one. I found module_eval does the trick (class_eval also works since it is a synonym for Module.module_eval). The final code is...


class Module
def attr_accessor( *symbols )
symbols.each { | symbol |
module_eval( "def #{symbol}() @#{symbol}; end" )
module_eval( "def #{symbol}=(val) @#{symbol} = val; end" )
}
end
end

class Foobar
attr_accessor :foo
private
attr_accessor :bar
end

fb = Foobar.new
fb.foo = "hello"
fb.bar = "world"
puts fb.foo # >> hello
puts fb.bar # >> world


Pretty simple. Unfortunately, this demonstrates the problem where my attr_accessor doesn't know about the Access Control. Looking at the Ruby library and source, I could not find any way to query the Access Control level from within my attr_accessor. So the only solution I could find is the following hack...


class Module
alias old_public public
alias old_private private
alias old_protected protected

def public( aSymbol = nil )
if aSymbol.nil?
@__module_access_level = 'public'
old_public
else
old_public( aSymbol )
end
end

def private( aSymbol = nil )
if aSymbol.nil?
@__module_access_level = 'private'
old_private
else
old_private( aSymbol )
end
end

def protected( aSymbol = nil )
if aSymbol.nil?
@__module_access_level = 'protected'
old_private
else
old_private( aSymbol )
end
end

def attr_accessor( *symbols )
symbols.each { | symbol |
module_eval( "def #{symbol}() @#{symbol}; end" )
module_eval( "def #{symbol}=(val) @#{symbol} = val; end" )
module_eval( "#{@__module_access_level} :#{symbol}; #{@__module_access_level} :#{symbol}=" )
}
end

@__module_access_level = 'public'
end

class Foobar
attr_accessor :foo
private
attr_accessor :bar
end

fb = Foobar.new
fb.foo = "hello"
fb.bar = "world" #>> private method `bar=' called for #<Foobar:0x2855710 @foo="hello"> (NoMethodError)
puts fb.foo #
puts fb.bar #



Anyone got a better idea for handling Access Control?

Tuesday, May 16, 2006

Rubyham

It has been over a month since my last post. I have been playing around with Ruby Rails in the little spare time I can find. Sometime I might post more of my experiences with it.

In breaking news, Birmingham is getting a Ruby users group named Rubyham. Kicked off by Josh Adams, Kevin Russell and Myself. It will be fun!

Playing with Rails, I used the Act As Authenticated plugin. The plugin seems to work fine. When adding the User Activation feature, I found a few changes were needed to make me happy. I have posted them back to the User Activation page. Here is the revision with my changes at the bottom.

Monday, April 03, 2006

SQL on Rails


Looks like Rails is taking over the world. Here is the first new langauge fork of Rails that implements all the Rails goodness: SQL on Rails

The a short screen cast is located HERE. Eight minutes that will change your life.

Sunday, March 05, 2006

Using SSL with Ruby http-access2

Expanding on my Ruby scripts, I wanted to download information from my yahoo account. Using Ruby to get HTTP is super easy. For example, the following will print the contents of http://www.w3.org/
require 'http-access2'
client = HTTPAccess2::Client.new()
puts client.get('http://www.w3.org/').content


Sometime later, I may post some examples of parsing HTML which is also super easy. For now I will talk about getting SSL to work.

Ruby http-access2 is a great library for writting web servers and clients. In this instance I am writting a simple client to login to yahoo and download information like my bookmarks. To login to yahoo, Ruby must use SSL.

It turns out that calling SSL from ruby is pretty easy. Just add the SSL configuration information. [Also, I changed the URL in this example.]
require 'http-access2'
client = HTTPAccess2::Client.new()
client.ssl_config.set_trust_ca('ca.cert')
puts client.get('https://login.yahoo.com/config/login?').content


This works great, if you have the correct certificate. If you don't (which happened to me), you get the message:
at depth 0 - 20: unable to get local issuer certificate
http-access2.rb:1001:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)
from c:/codetiger/ruby/tools/ruby/lib/ruby/site_ruby/1.8/http-access2.rb:1001:in `ssl_connect'
from c:/codetiger/ruby/tools/ruby/lib/ruby/site_ruby/1.8/http-access2.rb:1363:in `connect'
...

Figuring out what caused this error was a little confusing because of the "unable to get local issuer certificate" message. It really means "Unable to validate the certificate of the host because the trusted root certificate was not found locally." Unfortunately http-access2's docs are almost non-existent. I eventually found this information from the cURL faq! cURL and http-access2 both use OpenSSL, so the faq about this error is correct. The error message in the stack trace was from OpenSSL.

To solve this error, I had to get the correct root certificate. This is easily accomplished. First, check the web page properties in your browser. For the yahoo page, you will find yahoo is signed by "Equifax Secure Certificate Authority". I'm using Windows XP, so all I had to do was go into Control Panel -> Internet Options -> Content tab -> Certificates -> Trusted Root Certificates -> select "Equifax Secure Certificate Authority" -> Export -> select Base 64 Encoding -> save to file (EquifaxSecureCertificateAuthority.cer). [Firefox did not have an export option.]

Now that the trusted root cert is in a file, Ruby can use it...
require 'http-access2'
client = HTTPAccess2::Client.new()
client.ssl_config.set_trust_ca('EquifaxSecureCertificateAuthority.cer')
puts client.get('https://login.yahoo.com/config/login?').content


Yahoo!!!

Friday, March 03, 2006

.Net in Ruby

While creating a simple backup script (see previous post), I needed to copy more than the file's data. The backup copy needed to include the meta-data that Windows keeps for the file. Ruby (and Java or Ant) can easily copy the contents of a file, but they don't know how to copy the meta-data. The solution is to use .Net, but I wanted to write my script in Ruby.

I found the Ruby/.Net Bridge worked like magic. For example to copy a file, just use...
require 'dotnet' # Ruby / .Net bridge
System.IO.File.Copy( srcpath, destpath )


The install of Ruby/.Net Bridge was very simple. Just download, unzip, and run deploy.cmd. The ease of installation made me very happy.

After I created my backup script. I wondered if this Bridge worked with .Net v2.0. So I took a spare machine and removed .Net v1.1 to make sure the Bridge could only use v2.0. Everything worked perfect!

The one area that I had trouble was handling .Net's Enum. In .Net, the FileAttributes class is an Enum which is also a bit field (see FlagsAttribute). Using the Ruby/.Net Bridge, I could not perform bit-wise math operations on the Enum. I asked the authors, who gave me a good solution using the Parse method. For example:
require 'dotnet' # Ruby / .Net bridge

def attributeRemove( fileattribute, attribute )
Enum.parse( System.IO.FileAttributes, (fileattribute.ToString().split(', ') - [attribute]).join( ', ' ) )
end

def setReadWrite( dospath )
attrs = attributeRemove( System.IO.File.GetAttributes( dospath ), 'ReadOnly' )
System.IO.File.SetAttributes( dospath, attrs )
end

The last feature that I wanted, was to decrypt files and folders that were stored in encrypted file systems. Since Windows encryption used a key tied to the machine and user, the backup should not stay encrypted. If the machine failed it may be impossible to get the necessary key to decrypt. Unfortunately there wasn't a .Net method to decrypt the file or folder. Instead I had to call the win32api. This was pretty easy to do (however, I found the available documentation very lacking.) The following is a combination of some Utility methods, and the DecryptFile method I created for my script.
require 'Win32API'
require 'dotnet' # Ruby / .Net bridge http://www.saltypickle.com/rubydotnet/ just download it, uncompress and run deploy.cmd (per instructions on site)

class Utils
def Utils.attribute?( dospath, attribute )
if attribute.is_a?(String)
return System.IO.File.GetAttributes( dospath ).ToString().split(', ').include?( attribute )
else
raise "attribute parameter must be a String. attribute.class=#{attribute.class}"
end
end

def Utils.attributeAdd( fileattribute, attribute )
Enum.parse( System.IO.FileAttributes, fileattribute.ToString() + ', ' + attribute )
end

def Utils.attributeRemove( fileattribute, attribute )
Enum.parse( System.IO.FileAttributes, (fileattribute.ToString().split(', ') - [attribute]).join( ', ' ) )
end

def Utils.setReadWrite( dospath )
attrs = Utils.attributeRemove( System.IO.File.GetAttributes( dospath ), 'ReadOnly' )
System.IO.File.SetAttributes( dospath, attrs )
end

def Utils.setReadOnly( dospath )
attrs = Utils.attributeAdd( System.IO.File.GetAttributes( dospath ), 'ReadOnly' )
System.IO.File.SetAttributes( dospath, attrs )
end
end

class Win32API
def Win32API.DecryptFile( dospath )
Utils.setReadWrite( dospath ) if isReadOnly = Utils.attribute?( dospath, 'ReadOnly' )
result = Win32API.new('Advapi32', 'DecryptFile', %w(p i), 'i').call(dospath,0)
#todo better error checking
if result == 0
Utils.setReadOnly( dospath ) if isReadOnly
raise "DecryptFile call failed on path: \"#{dospath}\". see also: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/decryptfile.asp"
end
Utils.setReadOnly( dospath ) if isReadOnly
return result
end
end


An example usage...
if Utils.attribute?( path, 'Encrypted' )
Win32API.DecryptFile( path )
end

Monday, February 20, 2006

About: Format My Source Code

Several times I have wanted to post code to my blog. Only to find the process frustrating. To put the code on a blog you have to convert the source text into HTML. This also involves converting tabs to spaces; converting special characters to HTML encoding; setting a nice fixed-width font; and fixing a couple of other minor issues.

After searching around, I found a web page that would format C# and other Microsoft languages at C# code format. Which was great for C#, but I wanted to post Ruby, Java and other languages. My answer was to code my own source code to HTML converter. After hacking a little java-script, I have created:

Format My Source Code

The application is just a little bit of Java Script and DHTML to perform the conversion. I decided to publish it on blogspot since it was a tool for blogging. Getting everything to fit in the confines of a Blog page was a little limiting. I might change the layout when I've got more time.

The application has a few interesting features. When you press the "Format" button, I have the output section perform a yellow fade which was invented by Matthew Linderman at 37 Signals. I modified their technique a little to adjust the timing.

One problem I encountered was Blogger's editor. The "Compose" option would eat vertical pipe characters: |. Since my favorite language Ruby uses this character a lot, I tried hard to find a way to fix it. But "Compose" would always remove the characters. Fortunately, the "Edit HTML" option leaves the | character alone. So I added the detection of this character and a small warning will display.

To increase the usability, I added some code to automatically select the first input when the page loads. So a simple ctrl-v will paste into the input field without requiring any additional typing or mousing. Likewise, the generated HTML is automatically selected so all you need is to hit ctrl-c to copy to the clipboard.

I have the example output clipped to 25 lines. Also, if Embed Stylesheet is not used, an example style sheet will appear.

Enjoy!

If you are curious, here is the source code (at the time it was first posted):
<head>
<!-- THIS STUFF GOES IN THE HEADER TEMPLATE -->
<style type="text/css">
pre.source-code {
font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;
color: #000000;
background-color: #eee;
font-size: 12px;
border: 1px dashed #999999;
line-height: 14px;
padding: 5px;
overflow: auto;
width: 100%
}
p.warning {
color: #000000;
background-color: #FFB6C1;
font-size: 12px;
border: 3px double #333333;
line-height: 14px;
padding: 5px;
overflow: auto;
width: 100%
}
</style>
<SCRIPT LANGUAGE="JavaScript">
<!--
var Color= new Array();
Color[1] = "ff";
Color[2] = "ee";
Color[3] = "dd";
Color[4] = "cc";
Color[5] = "bb";
Color[6] = "aa";
Color[7] = "99";

function fadeIn(where) {
if (where >= 1) {
document.getElementById('fade').style.backgroundColor = "#ffff" + Color[where];
if (where > 1) {
where -= 1;
setTimeout("fadeIn("+where+")", 200);
} else {
where -= 1;
setTimeout("fadeIn("+where+")", 200);
document.getElementById('fade').style.backgroundColor = "transparent";
}
}
}

function format() {
var strIn = document.getElementById("textin").value;
var strOut = null;
if ( document.getElementById("embedstyle").checked ) {
strOut = "<pre style=\"font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%\"><code>";
hideElement("style");
} else {
strOut = "<pre class=\"source-code\"><code>";
showElement("style");
}
var strOut25 = null;
var line = 1;
var strTab;
var hasVerticalPipe = false;

if ( document.getElementById("tab4").checked ) {
strTab = " ";
} else {
strTab = " ";
}

for ( i = 0; i < strIn.length; i++ ) {
var code = strIn.charCodeAt(i);
switch( code ) {
case 9: // tab
strOut += strTab;
break;
case 10: // line-feed
case 13:
strOut += "\n";
line += 1;
if ( line == 26 ) {
strOut25 = strOut + "[only the first 25 lines shown in this example]\n\n";
}
if ( code == 13 && (i + 1) < strIn.length && strIn.charCodeAt(i + 1) == 10 ) {
i++;
}
break;
case 34:
strOut += "&quot;";
break;
case 38:
strOut += "&amp;";
break;
case 60:
strOut += "&lt;";
break;
case 62:
strOut += "&gt;";
break;
case 124: // vertical pipe (blogger modifies this)
strOut += "&#124;";
hasVerticalPipe = true;
break;
default:
if ( code >= 32 && code <= 127 ) {
strOut += strIn.charAt(i);
} else {
strOut += "&#" + code + ";";
}
break;
} // switch
} // for
strOut += "\n</code></pre>";
var textoutelement = document.getElementById("textout")
textoutelement.value = strOut;
textoutelement.focus();
textoutelement.select();

if ( hasVerticalPipe ) {
showElement( "vert-pipe-warning" );
} else {
hideElement( "vert-pipe-warning" );
}

var resultselement = document.getElementById("results");
if ( strOut25 != null ) {
resultselement.innerHTML = strOut25;
} else {
resultselement.innerHTML = strOut;
}

fadeIn(7);
}

function onloadEvent() {
var textinelement = document.getElementById("textin");
textinelement.focus();
textinelement.select();
}

function showElement(strId) {
var ref = document.getElementById(strId);
if ( ref.style) { ref = ref.style; }
ref.display = '';
}

function hideElement(strId) {
var ref = document.getElementById(strId);
if ( ref.style) { ref = ref.style; }
ref.display = 'none';
}
//-->
</SCRIPT>
<!-- END STUFF GOES IN THE HEADER TEMPLATE -->
</head>
<!-- THE BODY ELEMENT NEEDS THE ONLOAD EVENT -->
<body onLoad="javascript:onloadEvent()">
<!-- THIS STUFF GOES IN POST -->
<form>
<p>
<textarea wrap="off" rows="5" cols="50" id="textin">Paste your text here.</textarea><br/>
<table>
<tr>
<td><button onclick="format()" type="button">Format Text</button></td>
<td>
Tab size: <input type="radio" name="tabsize" id="tab4" checked="true">4</input> <input type="radio" name="tabsize" id="tab8">8</input><br/>
Embed Stylesheet: <input type="checkbox" id="embedstyle" checked="true"></input><br/>
</td>
</tr>
</table>
</p>
<p>
<div class="step-instr" id="fade">Copy the HTML below to your clipboard. Insert the HTML of your blog or wiki.<br/>
<textarea wrap="off" rows="12" cols="50" id="textout">formatted HTML will appear in here.</textarea></div>
</form>
</p>
<div id="vert-pipe-warning" style="display: none">
<p class="warning">
<b>Vertival Pipe Character Warning:</b><br/>
The text contains the vertical pipe character '|' which Blogger's editor may remove. Blogger's editor on the web has two edit tabs: "Edit HTML" and "Compose". The "Compose" tab will remove all | characters! Use the "Edit HTML" tab only.
</p>
</div>
<div id="results"><pre class="source-code"><code>This is an example of what your text will look like.
&#8226; Tabs are converted to spaces.
&#8226; Quotes and other special characters are converted to HTML.
&#8226; Everything is enclose in HTML's 'pre' and 'code' tags.
&#8226; Style is set:
&#8226; Fixed width font.
&#8226; Shaded box.
&#8226; Dotted line border.

</code></pre>
</div>
<p>
<div id="style" style="display: none">
Example Stylesheet:<br/>
<textarea wrap="off" rows="13" cols="50" id="textout"><style type="text/css">
pre.source-code {
font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;
color: #000000;
background-color: #eee;
font-size: 12px;
border: 1px dashed #999999;
line-height: 14px;
padding: 5px;
overflow: auto;
width: 100%
}
</style></textarea>
</div>
</p>
<!-- END STUFF IN POST -->
</body>

Thursday, February 16, 2006

JUnit 4.0 is here!

Download: http://sourceforge.net/project/showfiles.php?group_id=15278&package_id=12472&release_id=394034

v 3.8.1 was release in September 2002. It has been a long time since the last update. V4.0 requires Java5, as it uses annotations to mark tests.

Monday, February 06, 2006

VMWare Server for Free :)

VMWave is making a new VMWare Server product available for free. See http://www.theregister.com/2006/02/03/vmware_goes_free/ for a better write up.

Friday, January 20, 2006

.Net Generics vs Java Generics

I'm a big fan of Java. It is nice to see the fan base for Java is still far above .Net (and outpacing .Net in growth); see http://www.tiobe.com/tpci.htm

One area I've found .Net outshines Java is the implementation of Generics. Java's Generics exist in source-code only. The Java compiler "Erases" the generic information after the compiler determines that everything is correct. This approach outshines C++ templates, but it creates a lot of other issues. See the Java Generics FAQ which lists pages of special rules and edge cases caused by Erasers. Java Generics is more complex than Java the language!

.Net Generics on the other hand are implemented at runtime. So the Generic type information is not lost and is available through reflection. When the .Net CLR encounters the usage of a Generic type for the first time, it instantiates a non-Generic type based on the type parameters. The Generic type is never executed, it is just used by the CLR to create concrete instances. So Array<string> and Array<float> are two seperate classes at runtime. Java would have just used Array. So .Net memory grows a little more (but not like the bloat of templates in C++), which is a great trade off since it avoids the problems and complexities of Erasures.

Thursday, January 12, 2006

Stop running that startup junk.


A friend asked me how to stop some of those annoying programs that always startup when he starts windows. The best solution I've found is a freeware tool Autoruns from Sysinternals (http://www.sysinternals.com/Utilities/Autoruns.html). Autoruns is a powertool that gives you easy access to everything that is executed at startup. Autoruns allows you to simply uncheck the programs that you don't want to run.

Sysinternals has a number of great tools for performing other tasks. For example, Regmon and Filemon are handy to see what is really going on when installing a program. They are also handy for debugging programs.

Sunday, January 08, 2006

From Ant to Ruby - 122 lines of fun

Last month a friend of mine had a disk failure. Fortunately most of his files are still in good shape. Right now, he is going through the difficult process of trying to recover what files he can. This task is extra difficult since Windows XP encrypts everything under the 'My Documents' folder so that other accounts and OS cant read them. If you are not doing regular backups, you are just asking for trouble.

For almost a year now, I've used a simple Ant script to backup my files. I use a very simple method of copying everything to a separate drive using Ant. The backup also has a few extras that require special steps. For example, backing up my subversion repository requires calling the subversion svnadmin hotcopy command. I've been happy with this process until I wanted to automate backing up data I have stored on the internet. For example, my bookmarks and address book are in yahoo. So I had to manually export them from yahoo to a file, then run my backup script. I looked at using Ant's 'Post' task to automate the web stuff, but I was really unhappy that it wasn't very nice code. Also it was hard to verify that everything worked correctly. If yahoo ever changed a page, the backup might stop getting my data and Ant wouldn't tell me.

So I decided to convert the backup to one of my favorite languages Ruby!

My first task was just a straight conversion of my Ant script to Ruby. The original Ant script was 122 lines of code. When I finished the Ruby version, it came to exactly 122 lines of code! Very funny! This completely surprised me. I had thought Ruby would take more lines of code than Ant. In Ruby I had to write a lengthy backup function (40 lines), and add a few convenience functions. However, when I finished the initial conversion they came out to exactly the same number of lines.

Right now I'm adding more advanced features to my script. Which I will blog about later.