Friday, March 5, 2010

Mechanize and MultiSelect fields

Mechanize is a little handy tool that allows you to perform all sorts of HTTP requests in Ruby. It automatically emulates all sorts of browsers, handles cookies, headers and stuff, which is really useful when you need to harvest some data from sites that don't have any computer friendly feeds.

I'm using it on my current project and run into a small problem. It doesn't work nicely with array data, like for example multiselect fields emulation, so when you do something like that

agent = Mechanize.new

agent.post('http://boo.boo/boo', {
'param[]' => ['one', 'two', 'three']
});

In the reality it sends the 'one' value only. I've sent a little patch to the devs, but it seems like it will take time before they do something about it. So here is how you fix it in your rails app.

In any initializers in your `config/initializers/` directory add the following lines.

class Mechanize::Form::Field
def query_value
if @value.is_a?(Array)
@value.collect{ |v| [@name, v || '']}
else
[[@name, @value || '']]
end
end
end

After that it will be just fine.

Tuesday, March 2, 2010

My Top 5 on that RightJS vs. jQuery Question

During the last several months of RightJS promotion, the absolute hit among the questions of 'what?' and 'why?' was understandable the question of what is the difference between RightJS and jQuery.

There were lots of talks about RightJS speed and then more about speed, and then we had some abstract talks about its philosophy and its way among the others and we also have that simple comparison page.

And what I find important in a brainwashing process is systematicness and methodicalness. We did some talks on an abstract matter, we did some talks on the opposite side of scale with performance tests, now lets touch something real. Something in the middle. And probably summarize some previous talks.

So here it is, your next session; my top 5 as I see it at this morning.


1. Syntax

When I'm saying "jQuery is like PHP", first of all I mean the nature of its syntax. When you boil it down to the essence, both of them are just collections of helper functions. And as PHP defines a new kinda language upon C, almost the same way jQuery defines a new language upon JavaScript.

RightJS on the other hand is built right into JavaScript itself. In 90% it is the good old JavaScript, where we bring features from later JavaScript specifications and spice it with some standard features from more serious dynamic languages like Ruby and Python.

As the result, when you learn jQuery, you mostly learn jQuery, I've seen many nice fellas around, who know jQuery quite well, but stuck when they needed to do simplest things in pure JavaScript.

When you learn RightJS, you learn the actual JavaScript, yes we have some funny shortcuts and features that make mature web-developers happily giggling like school girls, but all of them are built upon JavaScript standards.

RightJS makes you do the things in JavaScript and do them right. And because of that, whatever the future brings, your knowledge and skills will remain with you.


2. The Actual STL

When I read someone saying "jQuery is the JavaScript STL", it usually makes me laughing so much, that my neighbors probably think that I've finally went nuts and going to blow off the Kremlin.

Now, don't get me wrong, I have no problems with jQuery's popularity and I respect that. Well, at least, as long as it keeps me away from people who doesn't know the difference between popularity and standards.

jQuery is a DOM DSL at best. First of all it doesn't have anything to do with JavaScript itself, because it's a DOM wrapper, secondly there is nothing standard about jQuery in terms of JavaScript. Take for example a look at the .each() function where the arguments are in just the opposite order than they are in the JavaScript own Array#forEach method.

If you need something that actually follows the standards, you should take a look at RightJS. It brings many standard features from later JavaScript specifications, plus many other none the less standard features from server-side programming languages, for example methods like String#startsWith or Array#random.

The DOM interfaces are just one part of RightJS and it has much more. We even have a build of RightJS without DOM features which you can use on the server-side with Node.js or say writing scripts in Qt.


3. Multiple Paradigms

As jQuery is simply a wrapper over DOM interface, it doesn't give you any alternatives but use its own way of dealing with the things. Yes, you might imagine that you're practicing Lisp in JavaScript, but the reality is that 99% of jQuery code (including jQuery itself) is just a spaghettish pieces of crap.

RightJS on the other hand is not just a DOM wrapper, it is a multi-paradigm framework. We have an advanced OOP stack that allows you to write clean and properly designed applications that are easy to support and refactor. We also have most of the standard FP features, like binding, curring, chains and stuff. We also have some standard native units extensions that are most helpful in procedural programming.

RightJS gives you options and flexibility, so that you could deal with your work in the most effective way.


4. Open Sandbox

Maybe jQuery forces you to write a spaghetti code, but there is a bigger problem. Most of jQuery and its plugins code are closed behind anonymous scopes that makes it impossible to change them part by part.

You know, people are actually already invented OOP, inheritance, functionality injection and other fancy stuff to deal with those sort of things. And that's why in RightJS we have radically opposite architecture.

RightJS is built using proper OOP structures and modules and it represents an open sandbox where virtually everything is accessible and customizable. You can easily bend and tune RightJS for your needs, changing and replacing its parts, adding your own features, methods and so one.

And because of that it is super easy to write any sort of plugins and extensions for RightJS. Take for example a look at the right-rails plugin; couple of dozens of lines of code and RightJS API was completely transformed to have the naming system of Ruby, with underscored syntax and other features.

RightJS gives you the same flexibility and hacker's joy as Ruby or Python.


5. Official Plugins

I'm sure you know what they say "jQuery has a gazillion of plugins that will do everything for you". It kinda reminds me other folks who was saying "Everything in Java has already been done".

Normal people usually add on that "badly".

That gazillion of plugins has actually a pretty nasty back side. The problem is in the closed architecture and inflexibility. For every case there are usually half a dozen of implementations, and quite often the choice is like "bad, bad or bad?". At the end you might spend more time looking for a proper plugin than you could spend writing it yourself, and at the finish your app will look like a Frankenstein, all stitched of different parts.

Yes I know, I know, Frankenstein is a romantic figure in gothic culture, but there is so few romantic in supporting such an app.

With RightJS we don't have the luxury of too many plugins, but we have several good points on that matter too. First of all, many common and frequently used features that you have as plugins for jQuery, are already baked into the RightJS core, like for example, additional form features, Ajax via iframes functionality, cookies and stuff.

Then we have all the standard plugins, like D'n'D, JSON, Behaviors, plus most of the standard UI elements like Calendar, Autocompleter, Tabs, Lightbox, etc. already implemented and served in the official plugins repository.

And what's different about RightJS plugins is that all of them are implemented in the same way, using the same set of rules. All events handling, options, usage principles all are the same. So that if you had experience with one plugin, you will be familiar with the rest of them too.

Then all the plugins follow the open-sandbox principles of the RightJS Core. All of them are implemented using proper OOP approach and can be easily extended using inheritance, functionality injection or even monkey patching if you will.

This way you don't need a dozen of variations of the same plugin, you can easily tweak any standard one to do exactly what you need.

Friday, February 26, 2010

Native Element#classList in FF 3.6 Against RightJS

As many of you probably aware, FF 3.6 has the HTML5 Element#classList feature implemented natively. And then @DouweM asked if we could add it to RightJS.

Well, I tried, but the thing is that those guys at Mozilla could do it better. They have the test, the picture and yet another 2x times performance improvement, awright.

But lets check it out by ourselves, shall we?

I've created this little script which has two implementations, one uses FF 3.6 native feature, another one uses the same pure JavaScript algorithm we use at RightJS to handle css-classes. And here's a screenshot of my test-run.



Seems like RightJS implementation murks a native feature again. It's more than three times faster on classes adding :)

So how did those guys at Mozilla get their results?

They simply used lousy RegExp based implementation of the feature in their test. Surely it was slower.

This is pretty much it. Hope they will fix it in the next releases of FF.

Saturday, February 20, 2010

Recent jQuery Performance Updates

Now folks, you know, I was always saying "there is nothing like a smell of good statistics in the morning!". Now lets take a look at that 2x speed up claimed over here.

I'm using my Shakker util to perform the tests. You can also read why I don't use Taskspeed anymore.

So to the tests. Lets take a look at the Firefox test



Yea, kind a bit of speed up at claimed `bind`, `html` and `remove` methods, certainly not 2x, and note how it actually got slower at 1.4.1 and then gets back to almost the same values as 1.4.0.

Now lets take a look at the same thing at Safari



A different scale, the same picture, it's getting slower from 1.4.0 to 1.4.1 and then gets back to almost the same values at 1.4.2. No 2x speed up between 1.4.2 and 1.4.1, more of that almost no speed up at all and certainly no 3x speed up agains 1.3.2.

Well, lets get further and take a look at the test in another fine browser, Chrome.



The same exact picture with the `bind`, `html` and `remove` methods, got slower on 1.4.1 and to the same value at 1.4.2.

Now you should get back to that release notes page and ask yourself "why there are no results for version 1.4.0?".

Yup, because there is no speed up, they merely fixed their own fuckups in 1.4.1 and now present it as 2x speed boost.
Awesome! :)

Slowing Things Down Under OS X

You know what they say "you need to slow down to see some certain things". In case of web-development, sometimes you need to emulate a realistically slow internet connection to see some problems with your project. See how quickly it loads up, how it receives the images, especially it useful to test file-uploads and ajax operations. So here is a little tip how can slow down requests to your local server to test the things properly.

Under OS X you have access to the FreeBSD traffic shaping util ipfw. First of all you need to define some rule which will work on local interactions.
sudo ipfw add 1 pipe 1 src-ip 127.0.0.1
sudo ipfw add 1 pipe 2 dst-ip 127.0.0.1

After that we can set up the connection speed, and also I like to add some delay to emulate a request to a remote server
sudo ipfw pipe 1 config bw 40Byte/s delay 100ms

After that all your local requests will slow down to 40Byte/s speed with a realistic 100ms response delay.

When you have done with your tests, you can remove the rule with the following command.
sudo ipfw delete 1

Now it is all interesting but lets wrap it up in a simple shell script so we didn't need to memorize all the fancy calls.
sudo touch /usr/bin/slowdown
sudo chmod +x /usr/bin/slowdown

After that open the file with your favorite editor and write the following little script

#!/bin/bash

if [ $1 = "clear" ] ; then

ipfw delete 1

else

ipfw add 1 pipe 1 src-ip 127.0.0.1
ipfw add 1 pipe 2 dst-ip 127.0.0.1
ipfw pipe 1 config bw $1KByte/s delay 100ms

fi

Now you can create and remove pipes just like that
sudo slowdown 40

And to remove the rule call it like that
sudo slowdown clear

That's all about it. Happy testing!

Sunday, January 31, 2010

Algorithm Complexity Analysis On An Interview

I was digging around trying to find what kind of questions Google interviewers ask potential candidates and found some guy story who was asked the following question:

"What is the complexity of searching for existence of all characters from one string into another?"

That guy answered "n*n", and after being rejected was wondering if it was "n*lg(n)". Poor little thing...

IMHO: Rule #1 when you're having an interview (I guess, especially at Google): "never trust the interviewer", it is their job and trade to mislead you and check how you actually think, rather if you know the correct answer.

So, here is how I would answer to that question. (yeah, I'm showing off, but please consider that as me simply exercising)

Okay. First of all the complexity vastly depends on an implementation. I can see at least three of them.

1. A blunt force solution, you just go through every character from the pattern string (p) and check if each of them exist in the text string (t). Strings are essentially arrays and search of any character in them have linear complexity. So that if we have n = |p| and m = |t|, then the overall complexity of the algorithm will be
O(n * m)

2. There might be another solution. If we pre sort the t string with say quicksort algorithm, then we can use the binary search, which has logarithmic complexity and faster than a blunt cell-by-cell search. In this case, considering that the quick-sort complexity is super-linear, the overall complexity will look about like that:
O(m * lg(m) + n * lg(m))

3. One more version. Considering that both strings consist of the same limited number of symbols, we can create two hash-tables, one will contain unique characters from the p string and another one will have characters from string t. As the alphabet is a limited list, finding of the intersection of those two tables will have a constant complexity. Plus we should add the complexity of building the hash-tables, which will be equal to the lengths of the strings. And the overall complexity will be
O(n + m + C) = O(n + m)

Roughly speaking, we can take a look at the case when n = m, then we can say the following about those three algorithms:

1. O(n*n) - quadratic complexity
2. O(n*lg(n)) - super-linear complexity
3. O(n) - linear complexity

I suppose the last one is the winnar.

--

This is about it.

I still do have that feeling that I'm gonna get my ass kicked in the upcoming interview, but at least I won't give up that easily and will throw couple of punches back.

Monday, January 25, 2010

How to Move Folders Between Git Repositories

Today I needed to move some folders from one git repository to another preserving the history. Evidently it's a tricky business, so here is how do that.

First of all you need to have a clean clone of the source repository so we didn't screw the things up.
git clone git://server.com/my-repo1.git

After that you need to do some preparations on the source repository, nuking all the entries except the folder you need to move. Use the following command
git filter-branch --subdirectory-filter your_dir -- -- all

This will nuke all the other entries and their history, creating a clean git repository that contains only data and history from the directory you need. If you need to move several folders, you have to collect them in a single directory using the git mv command.

You also might need to move all your content into some directory so it didn't conflict with the new repository when you merge it. Use commands like that
mkdir new_directory/

git mv my_stuff new_directory/

Once you've done commit your changes, but don't push!
git commit -m "Collected the data I need to move"

This is all about the source repository preparations.

Now go to your destination repository
cd ../my-repo2/

And here is the trick. You need to connect your source repository as a remote using a local reference.
git remote add repo1 ../my-repo1/

After that simply fetch the remote source, create a branch and merge it with the destination repository in usual way
git fetch repo1
git branch repo1 remotes/repo1/master

git merge repo1

This is pretty much it, all your code and history were moved from one repository to another. All you need is to clean up a bit and push the changes to the server
git remote rm repo1
git branch -d repo1

git push origin master

That's all. After that you can nuke the temporary source repository.