Sunday, December 27, 2009

Making a gem out of your ruby-on-rails plugin

Generally, now, when we have the gemcutter service, making a gem is not a brainer. Just find a similar project on github, copypaste its gemspec, then say gem build my.gemspec and gem push my.gem and you're basically done.

But there are some options you might want to know about.

First of all to that gemspec business, as I said, if you never did that before, you'd better just find a famous plugin on github that is more or less close to your project, copy its spec in a file named my-plugin.gemspec in the root of your plugin and fill it up with descriptions of your project.

You might find the gemspec option descriptions here and here. For example if you need to show the user some post install message, use the post_install_message option like that

spec.post_install_message = %Q{
Warning! Warning! Annoying message!
}

And one more, some gemspecs on github use plain lists of files that should go into the spec, sometimes with several dozens of entries. Don't do that. First of all, it will be pain in the ass for you, because you might just forget to update the list when you create a new file, second of all it will be pain for another people who might be interested in evolving your project. Ruby is a nice language and has everything you need to process those stuff automatically. For example like that

spec.files = Dir['lib/**/*'] + Dir['spec/**/*'] + %w{
README
LICENSE
CHANGELOG
}

For the second thing, you need to understand how rails hooks up plugins and gems.

When you create a ruby-on-rails plugin there is a file called init.rb in the plugin directory. When rails fires up, it adds your plugin lib/ directory to the load-path and then includes this init.rb file. Basically that's a good idea, you can keep the actual code clean in one place, and the dirty monkey patching script in another. This way you can test them separately and use separately, like say you want your module be available as is, outside of the rails stack, say with Rack apps or something.

But when it comes to a gem, it's a bit different story. Gem supposed to be just a standalone piece of code which you require from your application. It doesn't know anything about initialization, and when ruby-on-rails hooks it up, it just requires a file with the same name as the rubygem.

Say you have a plugin named super_duper then you will have a file lib/super_duper.rb, which rails will include when the gem is specified in the config. So, if you want to convert your plugin into a gem, you basically have two options. Include your init script into the super_duper.rb file, probably with some additional dirty conditions, or create another file like lib/super_duper_lib.rb and make your user define the gem in rails config like that

conf.gem 'super_duper', :lib => 'super_duper_lib'

Both are quite dirty and yet pretty common.

But, there is another, nicer option that lets you avoid disadvantages of those two approaches.

The trick is simple. All you need is to name your ruby-gem in a dashed style. Like say you have a plugin super_duper, so you create a ruby-gem named super-duper, after that you just create a file named lib/super-duper.rb with one simple line of code in it

require File.dirname(__FILE__) + '/../init.rb'

When ruby-on-rails hooks up the gem it will load the dashed file, which will load your init script. This way you can share your initialization script between plugin and gem, and you still keep your actual code clean and easily available outside of the rails stack with the standard require 'super_duper' call.

Friday, December 18, 2009

Meet Shakker The Mano-A-Mano JavaScript Performance Testing Suite

I've started this project after several months of using Peter Higgins's TaskSpeed library as the main regression testing utility during the RightJS framework development.

TaskSpeed is a pretty well done library, but many people (including me) were complaining about its tendency to mix different tasks in one, mainly the css-selectors and stuff, so sometimes it wasn't clear what's going on. Another problem was that it provides just a total time as the summary, which is not an exactly clean way of judging about frameworks relative speed.

So I started my own little script, which become a bit bigger script and that one become even bigger one, and bigger and bigger. And now we have for ourselves practically an alternative solution for the TaskSpeed library.

Meet The Shakker!

The first difference between Shakker and TaskSpeed is that, Shakker has a two-level tests structure, the first one drives the test and keeps the data, the second one keeps the actual framework test. This way we have real-live like data separation on one side, and a blunt feature-to-feature comparison on the other. Shakker counts only the actual feature run-time for every framework, skipping utility operations like elements search, preparing collections, and stuff.

Another difference is that, Shakker not just collects the time summary, it collects differences between framework results for every test and then calculates average values between all the tests. It also let you choose one framework and evaluate it against others. This way you can have an approximated relative frameworks speed comparison.

It also keeps the original by-summary results, so that if your love sucks, you always can choose another result.

So what all this gives to you? See for your self. I'm posting results for all the modern browsers below, browsing through them you can actually see now what's going on. For example, you can clearly see, that say RightJS slows down in the building and finding operations under IE7,6 because it has to extend all the nodes manually on those browsers. You also can see where optimizations for jQuery 1.4 go, and you can see how Dojo fastly unbinds event listeners, because it doesn't have an internal events registry and makes the developer keep all the pointers manually. You also can clearly see how RightJS rips off everything under Chrome and Safari, because it doesn't uses any special proxy for dom operations, and uses common Arrays, which those browsers heavily optimize.

Lots of interesting stuff.


Google Chrome



Firefox 3.5.6



Safari 4.0.4



Opera 10.10



Konqueror 4.3.2 (Ubuntu on VMWare)



Internet Explorer 8 (WinXP on VMWare)



Internet Explorer 7(WinXP on VMWare)



Internet Explorer 6(WinXP on VMWare)



All the tests were performed in OS X 1.6.2, on 2Hz macbook with 4GB of memory.

Sunday, December 13, 2009

FrontCompiler With Rubygem And Console Tool

FrontCompiler is a Ruby based JavaScript/CSS/HTML compressing tool of mine. It can create albeit packed JavaScript, works with DRYed CSS, can inline css in javascript, works as a Rails plugin, etc.

And as I use it quite a lot on my projects, finally, I've created a rubygem for it. It's available at the gemcutter service now.

http://gemcutter.org/gems/front-compiler

So if you use the project, you might just install it from there.

gem sources -a http://gemcutter.org
gem install front-compiler

Along with the rubygem I've added a simple console tool to work with the compressor

$ frontcc file1.js file2.js ....

It will automatically recognize the file type by its extension, so you can feed it with javascript or css or html. It will read them all, compress in a single string and spit it in the stdout. You also can mix javascript and css in one command to make the css be inlined in javascript.

Enjoy!

Saturday, December 12, 2009

RightJS vs. jQuery, Mano A Mano

After the RightJS 1.5 release, there was people hyping about RightJS being 6-8x times faster than jQuery. After that there was quite a fight about that and then funny boy Felix had posted an article which kinda says it's a bull.

Some people got it seriously, some people were complaining about the original test saying that the TaskSpeed util is not really representative case affected by css-selecters and stuff.

So I sat down and had written my own simple test, you can get it over here. This test eliminates any unnecessary disturbances, like elements selection, gets the questionable elements building process to the minimum and creates clean, pure functionality one-on-one performance test results.

The result is predictable and actually correlates pretty closely with the original TaskSpeed based benchmarks.


Google Chrome



Firefox 3.5.6



Opera 10.10


As you can see, in a blunt, face to face performance test, RightJS does murk jQuery several times.

Get use to it.

UPD: As I'm working on the test suite, I've added the pure-dom test and also publishing results for Opera.

Friday, November 20, 2009

RightRails The RubyOnRails Plugin For RightJS

In case you don't know, some time ago I started a ruby-on-rails plugin for RightJS called right-rails, which was just updated to the next version 0.3.0

There are actually quite a lot of interesting and fancy stuff going on and it tries to solve many of usual headache of ajax applications development.

Like say it transparently handling files uploading for remote forms, so that there is no difference if you have or have no files on your form. Plus there is a simple javascript interface for the most common ajax operations which is super easy in use.

Then there is a new much more powerful RJS scripting replacement, that allows you write javascript in ruby and more of that mix in one flow the serverside and browserside contexts, it has automatic types conversion and lots of other things.

Then small things like transparent Prototype/Scriptaculous helpers replacement for RightJS, plus various helpers for the RightJS own features and modules, plus automatic scripts including handler, etc. etc.

If you like RightJS and do ajax stuff in rails, check it out, you'll find many helpful stuff.

Saturday, September 19, 2009

Ajax Files Uploading With RightJS And Rails

I kinda stuck with the RightJS project for now and mostly write articles for the site.

But there is another interesting articles that lights up some details over the remote forms with files handling using Ruby on Rails and RightJS. There is also a link to a complete ajax photo gallery application that uses the featues.

Please take a look it is over here. I'm sure you might find some interesting stuff over there.

Saturday, August 15, 2009

RightJS 1.4.0 Is Out

And by the way, forgot to mention it in here yesterday. But RightJS was released yesterday with the brand new 1.4.0 version.

Mainly performance optimizations, some bug fixes and clean ups too.

Japanese Alphabet Training Machine

I'm trying to teach myself some Japanese. Well, sort of.

So I've written the application Happy-Nippo that might help you to memorize the first two, hiragana and katakana Japanese alphabets.

Looks quite nice.

Thursday, August 13, 2009

FrontCompiler Updates

FrontCompiler is a Ruby based JavaScript compression tool of mine. And I've just updated the self-builds feature of it.

Formerly it used a literal based hashes and special markers, and I've reworked it the way it used numbers and arrays, similarly how the Base62 encryption algorithm works.

Anyway. Now both, compression and decompression processes work faster, and the result builds are slightly (3-8%) smaller.

This is pretty much it. Enjoy!

Sunday, August 9, 2009

RightJS Now Rocks In IE8 Too

As you probably know, the new version of RightJS is coming. I've done some optimizations in the native css-selectors support in this version and now RightJS is the fastest one in IE8 too. The only condition, it has to have a correct document definition or to be switched to the XA-Compatible mode manually.

Thursday, August 6, 2009

RightJS Rocks In Firefox 3.5

A newer version of RightJS is coming, it will come with some further native method optimizations and now it beats everyone in the new upcoming Firefox 3.5

Saturday, August 1, 2009

HTML Code For A Close Button Icon

Some people like use chars and html-codes as a default content for buttons and links. The idea is to put some simple character or code which will look like an icon, and later, if necessary, replace it with a real icon at the css-level. A "close" button is a pretty common case and people usually use the "X" character in there. The problem with it is that it has wrong dimensions and doesn't look like a normal cross on a close button. Luckily there is a better way. There is a standard html code for the mathematical multiplication symbol ×.

It looks like that

×


As you see it has the correct shape of the close symbol, and it still a normal character which you can paint with css just as you like, use hover effects, etc.

Saturday, July 25, 2009

RightJS Is Faster Than Pure Dom

Well, I'm cooking a new version of RightJS. I've optimized this and that, tuned here and there. And then I've run the TaskSpeed test and it looks like RightJS works faster than pure dom.



That's not a fake, seriously, I've got this result from Safari 4. jQuery has in this test 883 points.

Sure, that's because of the way the original test was written, but the result is just hilarious 8)

PS: Goin' to publish the new version in the next couple of days

Thursday, July 23, 2009

Transparent Dates and Times Internationalization in Rails

The basic internationalization approach in Ruby on Rails supposes that you translate the dates and times like that

Created at: <%= I18n.localize @model.created_at, :format => :short %>

But most of us use the "to_s" method to format times, like that

Created at: <%= @model.created_at.to_s :short %>

Mostly because you usually don't think much about i18n when a project is just starting up, and then it's kinda sweet, nice and short way of doing that.

So, usually when it comes to the internationalization, the project is already pretty much covered with the to_s methods. If you were lucky you might had created a single helper method which processes all the dates and times in your project and then it's simple, but if you didn't you might think about highjacking the "to_s" method of the Time class. Like that.

class Time
def to_s(format=:default)
I18n.localize self, :format => format
end
end

But if you do so, you will probably broke the things. Because first of all the "to_s" method supposed to work like an alias for the "strftime" method, secondly this method is used to convert times and dates in the :db format and if it was not translated properly it will break your models, thirdly it's naughty when you completely replace such a method.

Okay here is a better way of doing that

[Date, Time, ActiveSupport::TimeWithZone].each do |klass|
klass.instance_eval do
define_method :to_s_with_i18n do |*args|
format = args.first || :default
if format.is_a?(Symbol) && format != :db
I18n.localize(self, :format => format)
else
to_s_without_i18n(*args)
end
end
alias_method_chain :to_s, :i18n
end
end

It keeps the original method and doesn't touch the custom and database formats. The ActiveSupport::TimeWithZone class is the Rails class for the UTC times you need to process it too.

Monday, July 20, 2009

Inline IE hacks with SASS

SASS is a nested css engine written in ruby. It's a pretty powerful and handy tool with lots of features inside, http://sass-lang.com

I'm using it on my current project and find it quite useful. The only thing which was bugging me is that I tend to use inline IE hacks in my css, like that

div.box {
cursor: pointer;
* cursor: hand;
}

And it seems like sass doesn't support such a feature, at least I haven't found it in their documentation.

But in reality it does actually has support of the feature, just it is not documented. It looks like that

#my-block
:cursor pointer
*cursor: pointer

Note, there should be no space betwen '*' sign and the property name

Friday, July 17, 2009

Customizing The Rails Forms Builder

The word "customer", usually means someone who come and say "I wanna custom stuff". And because it is their nature they do it all the time. Sometimes several times a day.

I'm skipping here the obvious question "why would I need to customize a forms builder?" and get straight to the point.

So you need to customize your forms. Big time. And if the first what comes on your mind are helper methods and partial templates, this article is for you.

And please don't think about monkey patching rails form-builder. Don't behave like a php developer thinking he can use rails. Lord save their poor souls.

There are better way of doing that.

First of all you should realize that in 99.99% of cases you should not change the default rails templates. Meaningly that

<% form_for(@model) do |f| -%>
<%= f.error_messages %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<% end -%>

Despite that it is a simple structure, with a little bit of imagination and css magic you can make it look like anything you need.

Secondly you really should pay a dollar of penalty every time you think about monkey patching. Ruby is not just a monkey patching language it is object oriented too, and rails form builder is a quite well organized structure.

Instead of patching, we will create our own form-builder using advantages of the inheritance and then swap the default builder from the built-in to our own one. This way we can change the logic of the forms building transparently for the templates, you even can have several form-builders which behave differently and swap them depend on the context.

The basic example would look like this. You create another helper module called FormsHelper and save it along with the other helpers in your application

module FormsHelper
def self.included(base)
ActionView::Base.default_form_builder = CustomFormBuilder
end

class CustomFormBuilder < ActionView::Helpers::FormBuilder
# your custom methods go here
end
end

Inside the class you will have access to the form builder context with all its built in methods and variables. For the beginning you should know about the following ones

  • @template - the template context, you call this variable if you need to call the basic helpers

  • @object - the current model of the form

  • @object_name - the string name under which the form knows the model


Okay now lets play with the thing a little. Say the customer says "don't like the <h2> header on the error reports, the one with the number of errors on the form". No problem, we just override the built in method

def error_messages(options={})
super options.reverse_merge(:header_message => nil)
end

Then say you as many other developers usually put your forms in a partial and then depends on the model state change the submit button caption. something like this

form_for(@model) do |f|
f.submit @model.new_record? ? "Create" : "Save"

This is a little bit annoying. Say I'd like just call it <:%= f.submit %> and want the form automatically set the caption. Here is the code

def submit(caption=nil, options={})
super(caption || @object.new_record? ? "Create" : "Save"), options
end

Then I got completely lazy and started to want my form builder to build a block of label + text-field in a single call, like this

form_for(@model) do |f|
f.labeled_text_field :name

# this should build the thing like that
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>

# you could do it like this
def labeled_text_field(name, options={})
@template.content_tag(:p, label(name) + text_field(name, options))
end

Then, all the sudden, your customer comes back and says a scary thing "I like this, but I want for this particular controller, there actually was the h2 header saying 'Oh noooo!'. Yes, just for this special case".

No, my friend we are not going to the monkey patchers hell! We just define another form-builder over our own builder, and automatically swap it in the particular controller

class SpecialFormBuilder < CustomFormBuilder
def error_messages(options={})
super options.reverse_merge(:header_message => "Oh noooo!")
end
end

class ParticularController < ApplicationController
before_filter :swap_form_builder

def swap_form_builder
ActionView::Base.default_form_builder = SpecialFormBuilder
end
end

Think you understand the idea. If you do the things in a serious way, lord will love you and grand you a big deal of flexibility and rapidness.

This is pretty much it. Have a good one!

Thursday, July 9, 2009

Decimal to Hex and Hex to Decimal in JavaScript

Generally JavaScript doesn't have a particular data type or class for hex values but it still provides couple of features which will let you work with hex data.

In similar to Ruby you can keep your hex values in strings and the convert them into decimal values back and forth.

var hex = 'FF';

var dec = parseInt(hex, 16); // -> 255

dec = dec + 255;

hex = dec.toString(16); // -> '1ff'

Tuesday, July 7, 2009

Psychic Abilities Test

I've created another toy, Psych Test.

The thing is fairly simple, you've seen it lots of times in movies. You have a standard 36 playing cards deck, and one by one you are trying to guess the next card suit color. Red or black.

Well... I'm not a psychic but I know what are you thinking.

"...50%...", right?

I bet, if you ask any of your friends or colleagues who is occupied in CS, mathematics or physics you'll have the same exact answer. But the thing is not actually that simple, and here is where the fun begins.

If you open up the link above and will click on the same exact prediction button during the whole test, the result will be exactly those 50%, well +/- 1% in some unlucky situations. You might repeat the test several times, it's pretty consistent almost without any deviations.

But if you will have the same test, but will actually try to guess the next card's color, you'll have a different result, usually in range between 40 and 60%. And you almost never will have 50% again.

You should try it to believe, you can check the source code too, there is no back door. Everything is fair.

So what do you think, how is that possible? Do you think it is you actual ability to predict the future affects the result?

I could tell a spooky story about underground CIA laboratories where they study those things since 60s, and that there is a standard measurement for such tests and an exact percentage which defines you as a proven psychic.

Or, if you prefer, we could think about the problem rationally. There are just four practically independent cases and two of them correct, so the result should be close to 50% every time, no matter which button you choose. But yet it's ain't like that.

As you understand this is not the test for a psychic abilities, this is a test for rational thinking.

Okay, I'm not going to marinade you any further, as you come here and read this far I owe you an answer.

The thing is simple but not that obvious. There's no mathematical or logical problem, every time you click any of those buttons, you've got an exact 50% probability to score. But in case when you click the same button all the time, you put your guess against an almost ideal random sequence generated by the computer. And that's why you have this pretty close 50% result every time.

But when you do the "guessing", your brain follows some patterns and tries to predict the next card. Yes, generally that's a random process and every guess as good as any other, but the distribution of those guesses in time is not such good as a random distribution generated by the computer. There are fluctuations and attempts to guess, which affect the quite short 36 cards selection and gives you the non 50% result.

The first time you test the computer's random numbers generator, the second time you test your own.

Sunday, July 5, 2009

Call vs. Apply

Today I'm going to tell you an educational story.

var f = function() {};

var test = function(callback) {
var time = new Date();
(10000).times(callback);
console.log(new Date() - time);
};

var test_with_apply = function() {
test(function() {
f.apply(this, [0,1,2,3,4,5,6,7,8,9]);
});
};

var test_with_call = function() {
test(function() {
f.call(this, 0,1,2,3,4,5,6,7,8,9);
});
};

(10).times(test_with_apply);
console.log('--');
(10).times(test_with_call);

The moral

119
122
118
118
128
119
120
119
119
120
--
55
56
55
55
55
55
55
56
56
55

Thursday, July 2, 2009

Sudoku Game In JavaScript and RightJS

In order to have some show off cases for my RightJS project I've written basic Sudoku Game.

Nothing really special but a quite nice implementation though. Check it out you will like it.

Wednesday, July 1, 2009

Sudoku Puzzle Generating, Pragmatic Way

Couple of days ago I described how you could generate a good random sudoku field, today I'm going to advocate for just opposite thing. There's no controversy in really, just there are different cases, when you should and when you should not do that.

You should or could write your own sudoku puzzles generator if you are particularly interested in the field and ready to spend lots and lots of time, getting deep in all the various rules which actually make a good sudoku. Well at least it will keep your self-esteem up.

But if you are just writing some implementation of the sudoku game, you actually better not to do that. And here is why.

  • Sudoku generating is a random process with generally unpredictable duration. There is a good chance that your generator will get unlucky and stuck. And a hanging over application is the last thing you want your user to see.
  • The process of generating of a really good, hard sudoku usually takes time, sometimes a few seconds
  • There are lots of rules you need to get into, implement test over, and then if you are not an expert in sudoku you wont be able to check it out if you have done everything properly
  • You will probably forget and never use again all the knowledge you gain during the implementation. I don't want to call it a waste of time, but I'm pretty sure there are better ways to actually waste your time.
  • A good sudoku generator might be quite big and complicated piece of software, which will be hard to test and support.

Luckily there are better ways to do that. Use other people's work to be precise. There are lots and lots of online sudoku generators, or you could use any desktop applications, most of them cache boards in files. I used the gnome-sudoku application, it lets you generate any number of sudoku and saves them in the files in the gnome configuration directory, or you can grab my archive right here puzzles.zip

What about the number of puzzles ask you? You need some storage to keep them and have big enough collection to keep the user happy.

Actually not, and here is the trick of the article. You actually can keep just a few puzzles for each level and then generate new puzzles out of the originals. You can safely do the following things with your puzzles

  • Rotate them
  • Flip in any way
  • Randomly shuffle rows and columns inside the 3x3 boxes
  • Shuffle rows and columns of the 3x3 boxes

As the result, if you say have initially a collection out of 16 puzzles, then you can rotate and flip it in 5 ways, then you can shuffle rows and columns in 9 ways in each of the nine 3x3 boxes, and eventually you can have 9 combinations of the 3x3 blocks.

16 * 5 * 9 * 9 * 9 = 58320

That's more than enough for your user never see the same puzzle twice in a row. More of that, all of those puzzles will be really consistent by the difficulty level because initially it is just the same puzzle.

And for the end you can see a possible JavaScript implementation right here boards.js

This is pretty much it. Have a good one!

Monday, June 29, 2009

Sudoku Random Field Generator

The task is simple, to fill up a 9x9 field by the sudoku game rules.

Generally it's not a rocket science and there are lots of simple solutions. For example filling up the field with shifted sequences. Say you have a sequence of numbers from 1 to 9, then you might generate a valid field like that.

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6

2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7

3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8

As you see, the principle is simple, you start with your basic sequence, and then shift it by 3 positions inside 3x3 box, and by one position between the levels. The principle will still work if you start with any randomly sorted sequence of unique numbers.

3 5 6 2 7 4 1 9 8
2 7 4 1 9 8 3 5 6
1 9 8 3 5 6 2 7 4

5 6 2 7 4 1 9 8 3
7 4 1 9 8 3 5 6 2
9 8 3 5 6 2 7 4 1

6 2 7 4 1 9 8 3 5
4 1 9 8 3 5 6 2 7
8 3 5 6 2 7 4 1 9

After that you might shuffle columns and rows in scope of boxes to make the field more random, you even might shuffle the 3x3 rows and columns as well to have even better results.

But this thing is not really serious and kinda boring. The problem is that all your numbers are grouped by three numbers and those groups in different orders will appear all over the field. And this might be used for cheating. Say you open one of the sequences 4 1 9 and then wherever you open any of those three numbers you immediately know the numbers next to it.

Well for smarty pants like you and me, we need something different, something bigger, better and more bad ass.

After several coups of coffee I've come to the following algorithm.

1. We generate our field row by row
2. For each cell in a row, depends on the other existing numbers in the 3x3 box or the column, we generate a list of options
3. Out of the list of options for each cell we randomly select a value
3.1 When we convert a list of the options into a row we watch for intersections with other options and choose the most optimal collection

For example we have the following thing

1 5 6 9 8 7 4 3 2
9 2 3 4 6 5 8 7 1
8 7 4 3 1 2 6 9 5

4 9 7 6 3 1 5 2 8
5 3 2 7 4 8 1 6 9
? ? ? ? ? ? ? ? ?
----------------------
The options will be following

6 1 1 2 2 9 3 4 3
6 8 5 5 7 4
8 9 7

----------------------
Out of the options we might create sequences

6 1 8 2 5 9 7 4 3
6 8 1 5 2 9 4 7 3
......

This way we will have no patterns and truly random valid sudoku field.

The only problem is that it is not exactly working.

As it's a random process, for each valid field there will be about 5-10 cases when there will be no ability to create a correct sequence. But despite the "not exactly" prefix, the algorithm is actually working and creates beautiful truly random fields.

And then you have a choice. Think about the algorithm by yourself and try to make it work every time, or you can make your computer think through the algorithm several times until a fully covered field will pop up.

Yes, I know, for a piece of software it sounds cheesy, but in reality there are not much calculations in the algorithm and make it running 5-10 times is not a big deal, it takes just a few milliseconds in javascript. Besides, if you need a speed, you can always cache the fields and shuffle them later as you shuffle the fields generated by patterns.

And for the grand finale here is a possible solution in JavaScript + RightJS

....
// generates randomly distributed field
generateGrid: function() {
var numbers = '123456789'.split('').map('toInt');
var matrix = numbers.map(function() { return []; });

for (var x=0; x < 9; x++) {
var options = [];

for (var y=0; y < 9; y++) {
var col_numbers = numbers.map(function(i) { return matrix[i-1][y]; });
var box_numbers = numbers.map(function(i) {
var box_x = (x/3).floor() * 3 + ((i-1) % 3);
var box_y = (y/3).floor() * 3 + ((i-1)/3).floor();

return matrix[box_x][box_y];
});

options.push(numbers.without.apply(numbers, col_numbers.concat(box_numbers)));
}

matrix[x] = this.sequenceFromOptions(options);

// drop and start over if there sequence was damaged
if (matrix[x].compact().length < 9)
return this.generateGrid();
}

return matrix;
},

sequenceFromOptions: function(options) {
for (var i=0; i < 9; i++) {
this.cleanOptions(options);

options[i] = [options[i].random()];
for (var j=i+1; j < 9; j++) {
options[j] = options[j].without(options[i][0]);
}
}

return options.map('first');
},

cleanOptions: function(options) {
for (var i=0; i < 9; i++) {
if (options[i].length == 1) {
for (var j=0; j < 9; j++) {
options[j] = options[j].length == 1 ? options[j] : options[j].without(options[i][0]);
}
}
}
}
....

Saturday, June 20, 2009

How Not To Create Rails Plugin

Another day I needed to handle some task which included communication with a SPARQL service. Quick google search gave me a reference to the ActiveRDF project, which claims to be the thing for ruby and rails.

But the thing is that the darn thing ain't work. As the matter of fact, you won't be able even run the example from the official site. I'm not complying, used the python sparql-wrapper to accomplish the task, but this project is a good example how you should not create a Rails plugin.

And here some tips and lessons you can learn out of it.

1. Location and Versioning Control System

The project was started at the https://launchpad.net service, under the bazaar versioning control system. That's probably a progressive thinking, but still a big mistake.

All the Rails crowd currently, more or less lives on git and github. The reason is obvious, all the people in one place, it is easy to participate in the projects using quick forking and merging. No need to register and set up your account. You do it once and have them all.

I had some experience with launchpad, it's a pretty good system, and if I would start some specific project for Ubuntu, I would probably thought about launchpad, but for Rails related project, if you want the people to participate you should go to github.

2. Implementation

The implementation as well a good example how not to write ruby code.

First of all when you creating an actual plugin or gem, global classes is the last thing which you should do. There should be the only one global name and this is the name of your project. All the rest of the things should be under the namespace.

The second is the API and what the users need to write in order to make it working in their application. With such a beautiful and powerful language as Ruby is, it is quite a shame to make people call the factory method directly. None of the actual rails part do that. There so much opportunities for all the meta-programming magic and you end up calling classes creation manually.

They should do it simultaneously to the existing things, like ActiveRecord or ActiveResource. As the matter of fact they probably should not start a standalone project in the first place and create some extension for the ActiveRecource project, they might make it to the rails codebase and that's huge. Much better than having another rails plugin.

But anyway, with a badly structured project, even if someone would like to participate and help it, that would be really hard and usually almost impossible to change anything, because there are already people who use the project as is, and people don't like to update their application code.


3. Support

I don't think I should mention such basic things, that when you have year and a half old bugs in your bug-tracker, even bugs where people already posted solutions and patches and you still didn't fix the problem, that's quite suck. As well as I should not mention such simple thing like keeping your code actually working, at least with the examples you have got on the front page.

The thing is that despite the fact that you are creating an open-source project and by the license you are not responsible for anything, you actually creating a project for people. Yes I know 90% of OOS just show-off projects by rookies just out of the university. But if you want the people to take you seriously you should support your projects.

Even if you don't want to work on the project anymore and there are no one else, you probably should say something, like "sorry guys the thing didn't fly and I have better things to do". Yes that suck, but that's understandable, and responsible.

If you didn't do that, people will still come and kill their time with your buggy code and will be left pretty much alone. You should warn your customers about such things, because everyone has different situations, someone probably would be happy to spend some hours to make a dead thing walking, but someone might be on a deadline and would expect your project actually working and probably would switch to something else if was warned.


The End

So the thing is simple. Bad location, bad implementation and bad support. This is more than enough to kill almost any project in any area. Think about it when you start your own.

Thursday, June 18, 2009

RightJS The First Public Version

After months and months of hesitations and struggling against my own perfectionistic habits I've eventually released the first version of my javascript library called RightJS.

Basically it's the fastest and compactest JavaScript framework at the day. And the coolest one too. Sure.

Well... Whatever. I wish the thing a long happy live and lots of ass-kicking experience.

Amen.

http://rightjs.org

Friday, June 12, 2009

Dynamic IFrames As Form Targets

Sometimes you need to submit a form through some hidden iframe, usually when you're trying to monkey an ajax request for a file uploading.

Usually you just render an iframe element along with the form in the html code and assign the target attribute of the form. Something like this

<form target="my-iframe">.....</form>
<iframe name="my-iframe"></iframe>

It works, but in cases when you try do the same thing dynamically with javascript. Say to wire some additional fancy callbacks or something. Say like that.

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.id = iframe.name = 'my-iframe';
window['my-iframe'].onload = function() {...};

var form = document.getElementById('my-form');
form.target = iframe.id;
form.submit();

This thing looks generally correct, but unfortunately won't work.

I'm not sure why, but I do know the way how to deal with it.

The trick is simple, dirty and cross-browsing. Just how we like it.

var div = document.createElement('div');
document.body.appendChild(div);
div.innerHTML = '<iframe id="my-iframe" name="my-iframe"></iframe>';
var iframe = document.getElementById('my-iframe');
iframe.addEventListener('load', function() {....}, false);
// or for IE
iframe.attachEvent('onload', function() {....});

var form = document.getElementById('my-form');
form.target = iframe.id;
form.submit();

This thing is perfectly works in all the modern browsers and old IEs.

And for the end, there is even better way. Try the new RightJS framework. Then the same thing will look like this.

$('my-form').send();

This is pretty much it. Have a good one.

Tuesday, June 9, 2009

Filenames Encoding Conversion Under Linux

If you need to mass-convert filenames from one encoding to another, say you are migrating from one distro to another and need to move the legacy data, you can do that with the convmv util.

# apt-get install convmv
# convmv -f cp1251 -t utf8 -r --notest /dir/name

Integers To Binary Or Hex Conversion In Ruby

There are some tips on how you convert integers to binary or hex numbers forth and backwards.

irb(main):019:0> 30.to_s(2)
=> "11110"
irb(main):020:0> 30.to_s(10)
=> "30"
irb(main):021:0> 30.to_s(16)
=> "1e"

irb(main):027:0> '11110'.to_i(2)
=> 30
irb(main):028:0> '30'.to_i(10)
=> 30
irb(main):029:0> '1e'.to_i(16)
=> 30

Tuesday, June 2, 2009

RightJS Visual Effects

Continuing having fun with RightJS. I've just published some basic visual effects library on the official site and created some simple playground where you can try this and that. Check it out, there are some fancy stuff.

http://rightjs.org/fx-demo

Sunday, May 31, 2009

RightJS Updates

There was some updates on the RightJS project. It moved to it's own github account, IE6 benchmarks were added and I'm working on some basic visual effects library for the framework. It does lots of fancy stuff and weight just 5k extra. Kinda sweet.

Tuesday, May 26, 2009

RightJS Kicks The Butts

RightJS, on the start was real fast on the WebKit browsers and just above average on other browsers. The difference is that on WebKit browsers it was using the native css-selectors. But after an optimization session on the RightJS manual css-selectors, now we can proudly say, that RightJS kicks all the other frameworks on almost any browser and any conditions.

Check it out on the page RightJS Benchmarks, there are tests for all the modern browsers, including IE and Opera. There's no test results for IE6 yet, because it has some memory leaking issues which were not fixed yet and slows the browser down. But rest of the results looks cool

Wednesday, May 20, 2009

Meet RightJS

I would not consider it like an official start, but say we are rolling out and so I started the official site for my RightJS prject. Right here.

http://rightjs.org

Thursday, May 14, 2009

Being Pragmatic about Agility

There is a book appeared recently called "Pragmatic Career" and there was a sentence in its annotation saying "when I started to look at my life throw the glasses of agility I started to see agile patterns just everywhere". Ok, that probably not the exact quote but the point is that some people getting the agility too far. They start to worship it almost as a religion and sure see its deeds just everywhere.

Don't get me wrong I'm not against agility and this is not another crapy article a la "agility sucks, I hate it". Nope, agile approach is a wonderful tool and I use it every day and pretty much happy with that. My point is that the agile approach is just a tool, you should use it wisely and be critical about it.

Agile approach works pretty well if you are an experienced developer, a ninja who knows how to give a good punch from almost any position. You don't plan too much, be flexible and if the things go a wrong way, you just adjust. It reduces the entry level, gives you ability to try this and that and see how is it going, etc., etc. You take all the advantages of the technique.

But when you are young, have a lack of experience and good habits, it might lead you to a wrong path. Because of it nature, people quite often start practicing the "shoot first think later" approach. They write crap and hope they will fix it later, don't write tests and documentation. They think that they are agile because they produce a lot of code and kinda buggy features which they gonna make better later. But in reality they go in circles over and over, and eventually spent an ugly amount of time.

Agile approach is not about creating crap now and make it better later, it's not about skip all the things you are too lazy to do or just don't know how to do. As the matter of fact, the original "Pragmatic Programmers" book in one of its tenants says directly opposite "Don't live with broken windows". More of that, any normal professional in any area will tell you the main rule of being effective "Do the things once and only once". If you need to get back and fix your solutions, you are just killing time.

Agility is all about flexibility and rapidness. It is a contradiction to the old fashioned heavy planning approach, a tool which lets avoid painful situations when you at the finish line and realize that you have not what you needed. With agile approach you do small steps, but it doesn't cancel the idea that you should do your steps right. You do small steps but each step should be done in a good way. If you rush to the end target, skipping steps and taking all the possible shortcuts, move by an unpredictable trajectory, at the end you will have something as much painful as if you was sticking to some wrong plan.

And the problem actually, the problem is in ourselves, it is in our brains, in the way it works. The mother nature designs the things the way they were working in the most effective way, consuming as less energy as possible, that's the matter of surviving, and our brains are not an exception. Instead of careful thinking, we tend to jump to conclusions based on our experience, on the things we believe. That's kind of solutions caching mechanism. And the agile approach fits it like a glove, you just make rapid decisions based on current situation and your guts and move forward.

The problem is that if you have right solutions in your cache/experience, you are good, but if you don't you'll go through all the problems and become one big pain in the butt, for yourself, for your colleagues and eventually for your customer.

And here we come to the sake of "evil" old planning.

Planning is getting evil almost the same way as anything else getting evil, including agile approach. When you overuse it. The sake of planning is that it lets you make the reality check, think critically, review your experience cache. You write some simple roadmap and ask yourself a question "How do I know what I know?". It lets you filter out problematic cases, make you aware about problems before you meet them. That's the way to make your brain actually work, not just return some first thing out of the cache.

The bottom line.

I think you've got the idea. Sometimes you should ask yourself what are you actually practicing when you are practicing an agile development? Don't you feel like going circles, getting back and fix the things all the time? How do you know about the decisions you made? Don't you call something useless just because you too lazy or just don't really know how to use it? If you have any hesitations, it's okay to stop, sit down and think about the things for 20 minutes, do some reality check, maybe even take a good old pencil and piece of paper and write down some short plan.

This will make you actually think about the things, which will make you better, and better you will produce a better work.

Monday, May 11, 2009

Who's Your Daddy?

There's a pet project of mine called "RightJS". Yup as you can see it from the name it's yet another javascript framework. Well kinda. At the moment it provides most of the useful features of Prototype, salted with some features from dojo and spiced with features from jQuery and MooTools. It weights just 28k and wether you know passes the taskspeed test just like that.



There's the test source http://github.com/MadRabbit/taskspeed .

Okay, okay. Don't hold your breath. It's just in WebKit. In FF it's faster than Prototype at about 20% and still slightly faster than jQuery. In Opera it about same speed as jQuery and a little bit slower than Prototype. In IE... Well... Who uses that obsolete browser anyway?

PS: I would not believe tests result for jQuery on the benchmark, case when Prototype and RightJS were honestly loaded with elements building, updating etc. But as jQuery does not have this functionality, tests for it just feed the results with strings of already created html. Kinda cheating, you know.

Monday, April 27, 2009

One Image Round Corners

I'd like to share with you some fancy idea how you make easily maintainable css-based round corners on your pages. It's quite a common feature those days and if you don't know how to do that it might be quite a headache.

The Idea

The idea is pretty simple. You create an image which contains all four of your box corners. Usually it's just a small circle or a ring. Something like that.



Then you create an html-tags structure, like this.

<div class="box">
<div class="corners top"><div class="left"></div><div class="right"></div></div>

<div class="data">
Your text goes here
</div>

<div class="corners bottom"><div class="left"></div><div class="right"></div></div>
</div>

It is not necessary to have the middle div.data, but it will provide you move flexibility for css-alterations in future, so you'd better have it in there.

And eventually you write some piece of css-code.

div.box {
padding: 8px;
}
div.box div.corners div {
height: 8px;
width: 8px;
position: relative;
float: left;
margin-top: -8px;
margin-left: -8px;
margin-right: -8px;
background: url('corners_image.gif') no-repeat 0 0;
}
div.box div.bottom div { margin-top: 0; }
div.box div.corners div.right {
float: right;
background-position: 100% 100%;
}
div.box div.top div.right { background-position: 100% 0; }
div.box div.bottom div.left { background-position: 0 100%; }

The stylesheet uses the images shading technique and displays a quoter of the image for each corner, so the pixel sizes in style definition should be equal to a quoter of your corners image. And the box by itself has some nice padding of the same size, so the box was looking visually correct and fit the corners.

This is pretty much it.

Why Do It Like That?

Well. There are several reasons.

a) It gets down the number of server requests to the server. For such tiny images, the actual loading time is the time of request and response to the server. So making it one image instead of four you make your page loading faster and don't bother your server.

b) When you have one image, you don't need to deal with each corner separately, you can unify and compact the styles, and then if you need, you can replace all the corners really easy but replacing just one image. It provides you really good flexibility in terms of css-based design. Take a look in here One Image Corners Example, I've created some demo for you. See how it's easy alterable for various cases. You just change the background color and image url and have another box ready to go.

c) With such approach in most cases your boxes will be still looking consistent if there is some problem with the image loading. User doesn't see unprofessionally looking cases when you have four separated images and one of them was lost or just when they are getting loading one by one. With one image the user will have all the corners at once, and if the image was lost, he will still see appropriate looking box on the page.


PS: If you need transparent backgrounds at the outer angles of the corners, you can have them on the same exact tags structure, but you will need some additional mambo jumbo in your stylesheet, which I didn't intend to cover in the article. But in 99.9% of good modern designs you won't need that anyway.

PPS: This certain css example does not work correctly on IE6, although it is entirely possible to make it working there, just I don't want to spend my free time on that zombie. If you need to support it you just put some additional adjustments into you css file with IE patches.

Sunday, April 5, 2009

FrontCompiler Updates

Finally I've found some time and implemented a new feature for the FrontCompiler project.

This feature compresses your javascript code by using the tokens dictionary mechanism and then create another javascript which will recompose your original javascript code on the users browser.

Reconstruction happens pretty quick, almost unnoticeable. And this gives you extra 20-40% of compression over the usual front-compiler compression, which as we all know is already better than the YUI compressor's.

Say the latest Prototype v1.6.0.3 was compressed from 138 kB to 59 kB. MooTools was compressed from 98k to 50k, etc.

You can grab the latest, already compressed files here http://stcamp.net/share/prototype/

Try it, it's just awesome!

Friday, March 6, 2009

MySql CaseSensitive Select Trick

By the default, mysql compares the strings case insensitively

INSERT INTO users (email) VALUES ('some@email.com');
INSERT INTO users (email) VALUES ('SoMe@EmAiL.cOm');

--- The following two selects both will return two records

SELECT * FROM users WHERE email = 'some@email.com';
SELECT * FROM users WHERE email = 'SoMe@EmAiL.cOm';

--- Even LIKE select will return the same two records

SELECT * FROM users WHERE email LIKE 'SoMe@EmAiL.cOm';


But there's a trick how you can run a case sensitive select on mysql, you should use the binary comparison for the strings like this.


SELECT * FROM users WHERE email LIKE BINARY 'some@email.com';
SELECT * FROM users WHERE email LIKE BINARY 'SoMe@EmAiL.cOm';


The first select will return the first record only, the second will return the second one.