I've launched new simple plugin for Rails/ActiveRecord.
This one extends the belongs_to associations between models and allows you to assign related units by one (or several) fields for the model. Say you have got a message which belongs to a user, and you would like to assign the user to the message by his login name. That's our case. Use the plugin and everything will be fine! 8)
http://github.com/MadRabbit/assign_by/tree/master
Saturday, November 22, 2008
Thursday, November 6, 2008
SearchableBy, the ActiveRecord plugin
I've created some simple plugin for Rails/ActiveRecord, which you can use for search methods definitions.
It is a simple stuff which just creates some named_scopes which you case use as various search methods.
Take a look at the README file at the repository http://github.com/MadRabbit/searchable_by there are some examples.
It is a simple stuff which just creates some named_scopes which you case use as various search methods.
Take a look at the README file at the repository http://github.com/MadRabbit/searchable_by there are some examples.
Friday, October 10, 2008
Writting own Form Helper for Rails
The plot of the story is following. Say I've got some simple models, like
A city belongs to a country and a customer belongs to a city. And then on the customer form I would like to have a select box of cities with selection groups by country.
Well, that's not a problem, we can do that.
Not pretty but works. But then we add another unit
Now each customer belongs to an office, and we would like to write another drop-down list with groups on the customer's form.
We have already got some not-pretty stuff on the form. So, what you gonna do about that?
Obviously we should wrap this puppy up.
How?
Well, that's the question.
Certainly we can write yet another method in our helpers, and be happy, but I would like to be not just happy, but feel myself kinda sexy as well. So, I would like to write it in such a way that it was look like a standard form-element. Like that.
How can we achieve such a beauty?
Simple.
You just need to know some simple things.
First of all, you should know about the existence of the class ActionView::Helpers::FormBuilder. This class is the class which instance you use in the forms building with rails. And that's the class we are going to extend.
The second thing you should know is the existence of the instance variables of the FormBuilder class, which you can use when you are building your own methods
The third thing you should know is how to extend classes and modules on fly. Say we create a special separated helper for our new form elements.
We define some module of ours, where new form-methods will be defined and then we include the module inside the FormBuilder class when our helper will get included to the system. And I've added some default values to the method, case my models all have uniform "name" method, so I didn't need to repeat that things over and over.
And voila, this is it. Enjoy!
Country
- name
City
- name
- country
Customer
- city
A city belongs to a country and a customer belongs to a city. And then on the customer form I would like to have a select box of cities with selection groups by country.
Well, that's not a problem, we can do that.
<%= select_tag "user[city_id]",
option_groups_from_collection_for_select(
Country.all, :cities, :name, :id, :name, @user.city_id
), :id => "user_city_id" %>
Not pretty but works. But then we add another unit
Office
- name
- city
Customer
- office
Now each customer belongs to an office, and we would like to write another drop-down list with groups on the customer's form.
We have already got some not-pretty stuff on the form. So, what you gonna do about that?
Obviously we should wrap this puppy up.
How?
Well, that's the question.
Certainly we can write yet another method in our helpers, and be happy, but I would like to be not just happy, but feel myself kinda sexy as well. So, I would like to write it in such a way that it was look like a standard form-element. Like that.
<%= f.grouped_collection_select :city_id, Country.all, :cities %>
<%= f.grouped_collection_select :office_id, Countries.all, :offices %>
How can we achieve such a beauty?
Simple.
You just need to know some simple things.
First of all, you should know about the existence of the class ActionView::Helpers::FormBuilder. This class is the class which instance you use in the forms building with rails. And that's the class we are going to extend.
The second thing you should know is the existence of the instance variables of the FormBuilder class, which you can use when you are building your own methods
@template
- this is a reference to the current template processing object. Each helper method you call in your templates can be called as the variable method inside the FormBuilder class.@object
- a reference to the current model instance which the form covers.@object_name
- the name of the model variable you use to build your form.The third thing you should know is how to extend classes and modules on fly. Say we create a special separated helper for our new form elements.
module FormHelper
def self.included(base)
ActionView::Helpers::FormBuilder.instance_eval do
include FormBuilderMethods
end
end
module FormBuilderMethods
def grouped_collection_select(method, collection, sub_name,
group_method="name", unit_id="id", unit_name="name")
@template.select_tag "#{@object_name}[#{method}]",
@template.option_groups_from_collection_for_select(
collection, sub_name, group_method, unit_id,
unit_name, @object.send(method)
), :id => "#{@object_name}_#{method}"
end
end
end
We define some module of ours, where new form-methods will be defined and then we include the module inside the FormBuilder class when our helper will get included to the system. And I've added some default values to the method, case my models all have uniform "name" method, so I didn't need to repeat that things over and over.
And voila, this is it. Enjoy!
Sunday, September 21, 2008
Nested Styles with Ruby and FrontCompiler
Nested styles is a feature which some people dream about for quite a long time. The idea is pretty simple and beautiful.
Say you have got some css like that.
And now imagine that you could write it with nested constructions like that.
See the difference? How much more simple, clean and DRYish your css could be! Unfortunately current browsers don't support such things. At lest not yet.
So, does anybody want to sit down and wait for the future coming?
No, say 'no', you don't need tell such terrible things, because we have added the feature emulation in the FrontCompiler project. Which is a JavaScript/CSS/HTML processor written in Ruby and which can be used as a Rails plugin.
From now one, each time when you process a css file with FrontCompiler, it will automatically convert your nested styles in the way browsers can understand. So you can easily and safe use the nested styles advantages.
Have fun!
Say you have got some css like that.
div.article div.title {
font-weight: bold;
}
div.article div.title a.author {
padding-left: 12px;
background: url('user.png') no-repeat left;
}
div.article div.text {
border: 1px solid #EEE;
background: #FEF;
}
And now imagine that you could write it with nested constructions like that.
div.article {
div.title {
font-weight: bold;
a.author {
padding-left: 12px;
background: url('user.png') no-repeat left;
}
}
div.text {
border: 1px solid #EEE;
background: #FEF;
}
}
See the difference? How much more simple, clean and DRYish your css could be! Unfortunately current browsers don't support such things. At lest not yet.
So, does anybody want to sit down and wait for the future coming?
No, say 'no', you don't need tell such terrible things, because we have added the feature emulation in the FrontCompiler project. Which is a JavaScript/CSS/HTML processor written in Ruby and which can be used as a Rails plugin.
From now one, each time when you process a css file with FrontCompiler, it will automatically convert your nested styles in the way browsers can understand. So you can easily and safe use the nested styles advantages.
Have fun!
Monday, September 15, 2008
FrontCompiler Update
I have updated the JavaScript part of the the presented recently FrontCompiler. I've improved the compression algorithm, got rid of some old bugs, rewritten the code in a more clear way and made it work several times faster.
So now, it's better, faster, cooler, nicer, whatever.
And I have compressed the Prototype / ScriptAculo stuff, with the new compressor and shared them at here.
Try it, that's nice and free! 8)
So now, it's better, faster, cooler, nicer, whatever.
And I have compressed the Prototype / ScriptAculo stuff, with the new compressor and shared them at here.
Try it, that's nice and free! 8)
Thursday, August 21, 2008
Javascript/CSS/HTML Compiler in Ruby
I have backed some pretty tasteful cookie in here!
Met FrontCompiler!
It's a collection of scripts which allows you to compact your JavasScript, CSS and HTML code to reduce the loading time, and it can be used with Rails/Merb/Whatever.
NOTE: in test of compacting the Prototype library the script beats famous YUI compiler on about 1 KByte.
Enjoy! 8)
Met FrontCompiler!
It's a collection of scripts which allows you to compact your JavasScript, CSS and HTML code to reduce the loading time, and it can be used with Rails/Merb/Whatever.
NOTE: in test of compacting the Prototype library the script beats famous YUI compiler on about 1 KByte.
Enjoy! 8)
Wednesday, August 6, 2008
The Mines Game in JavaScript
I have been playing a cool javascript hacker this weekend and as the result have implemented the well known game of mines in pure JavaScript/CSS/HTML. Take a look it's pretty nice.
JSMiner Game
JSMiner Game
Saturday, July 26, 2008
Ubuntu HDTV fix
I had a problem with Ubuntu on my old notebook with Intel Mobile 915GM video-card. It didn't want to play hdtv files, rips and some .mkv files. It had been crashing with an insufficient resources error.
The issue is simple, the video card uses the system memory for its own purposes, and ubuntu has wrong default xorg configuration for the videocard. Add the following three lines to your
This will fix the problem.
The issue is simple, the video card uses the system memory for its own purposes, and ubuntu has wrong default xorg configuration for the videocard. Add the following three lines to your
/etc/X11/xorg.conf
file into the Section "Device"
section (search for the Driver "i810"
line).
Option "VideoRam" "65536"
Option "CacheLines" "1980"
Option "LinearAlloc" "32768"
This will fix the problem.
Tuesday, July 22, 2008
TestCase 2.0.2 is out
TestCase - the kickass javascript testing framework has got new release with version 2.0.2
And I've launched the official support resource for the project, take a look, there is lot of interesting and useful stuff.
And I've launched the official support resource for the project, take a look, there is lot of interesting and useful stuff.
Sunday, July 20, 2008
Rails + Gettext Crash Course, Part 2
This is the second part of the first rails+gettext article. In this part we will take a look at some advanced points of using gettext and its bind to ruby/rails. Generally there is nothing "advanced", just say we move a little bit beyond elementary
That's all about the message definition methods.
But sure you have got your special cases and you can follow the next instructions. Say the usual case, a user model where you have got some virtual fields
As you see we have used the method
And another moment, we have used the 'User|' prefix in the field name definitions, this is to determinate in the translation which model the field name belongs, so you could have different translations of the field names for different models. By default it will be splat by '|' and the last token will be taken.
If you don't want to translate some particular field names, you may define to skip them by calling the
Sometime templates contain lots of text with big descriptions, so it is more comfortable to have another template file special for a particular language rather than put big pieces of text in the
If the current locale is 'ru', then the
The best way here I think is to follow the general ideology, separate parameter variables and the urls formatting, just as you do with say same ID parameter. A good solution would be define a parameter name which will point to the desired language, say
and then you left some options for youself how present it at your urls. You may use a simplest way like and left the gings as is
or you can handle the language by routes so your pages were more caching friendly
or later you may handle them by subdomains or something like that, whatever you choose your application code will not need changes.
--
Okay, think that is all what I had to say about using gettext with rails. Good luck!
_('some text')
calls.Interface
Except the_(String)
method, there are several more standard methods to define messages for gettext. Generally there are two parts of them, for singular and plural forms. The first ones take as the main argument your usual message string, the second ones two more arguments, singular form of the message, plural form of the message and an optional number which helps to determinate when it is a singular form and when it is a plural form.Singular methods
String _(String)
- the standard method as we now it. The method takes a string and returns its translated version.String s_(String message[, String div="|"])
- this one for the cases when you need to define a scope for the message, say you have just the same message in two different context which might have different translation. So you write a string likes_('context|phrase')
, your message will be splat by the divider ('|' by default) and if there is no translation the last part of it will be returned. Simple examples_('gender|sex')
ands_('activity|sex')
, by default both of them will return 'sex', but you may have two different translations of the word in different languages depend on the context.String N_(String)
- this one might look a little bit strange. It tells gettext to define in its base the given string as a message, but does not translate anything and returns the given string as is. Generally it does just nothing, it is a dummy method and just a marker for the gettext parser. You will be given some examples of its usage below.
Plural methods
n_(String msg, String msg_plural, Integer number)
- this one is same as_(String)
but for the plural cases. The first argument is a singular version of the message the second is the plural version of the message. And the last argument the current lets call it plurality marker by which gettext will define which message use. NOTE: despite that you pass here only two messages, when you translate your .po files you may define several (more than two) translations of the messages which will depend on the plurality marker.ns_(String msg, String msg_plural, Integer number[, String div='|'])
- same ass_(String[, div])
but for plural formsNn_(String msg, String msg_plural)
- same as theN_(String)
method but for plural forms
That's all about the message definition methods.
Models Internationalization
GetText by default has all the standard error messages translations for most of the languages inside the package. And the parser will automatically define translations for your model fields which are in the database (meant field-names translation). So you don't need to worry about that.But sure you have got your special cases and you can follow the next instructions. Say the usual case, a user model where you have got some virtual fields
class User < ActiveRecord::Base
has_one :profile
has_many :comments
attr_accessor :password, :password_confirmation
# we can define the virtual fields translation like that
N_("User|Profile")
N_("User|Comments")
N_("User|Password")
N_("User|Password confirmation")
# we can create custom error-messages in this way
validates_uniqueness_of :login, :message => N_('The login-name is already taken')
def validate
errors.add("password", _("%{fn} is wrong!")) unless password == password_confirmation
end
end
As you see we have used the method
N_(String)
for class initialisation calls and the method _(String)
inside the custom validation method. The point is simple, in the first case you don't really need the translation result, you just need to define some messages and the second case works in runtime so you need an already translated version of the message.And another moment, we have used the 'User|' prefix in the field name definitions, this is to determinate in the translation which model the field name belongs, so you could have different translations of the field names for different models. By default it will be splat by '|' and the last token will be taken.
If you don't want to translate some particular field names, you may define to skip them by calling the
untranslate(*names)
method like that
class User < ActiveRecord::Base
untranslate :login, :email
# or
untranslate_all
end
Templates Internationalization
In most cases of templates internationalization you just use the standard gettext methods, like<%= _('Some label text') %>
, but there is another way.Sometime templates contain lots of text with big descriptions, so it is more comfortable to have another template file special for a particular language rather than put big pieces of text in the
_(String)
function. It is simple, just create another file next to existing one but with a name which have a suffix named after the locale you want. For example
app/views/pages/
about.html.erb
about_de_DE.html.erb
about_ru.html.erb
If the current locale is 'ru', then the
about_ru.html.erb
file will be used, if there is no matching file, the default about.html.erb
file will be used.Language Switching Tactics
And at the end some points about the language switching tactic. If you are experienced developer you probably do not need this part, but I would like to spell some words about it.The best way here I think is to follow the general ideology, separate parameter variables and the urls formatting, just as you do with say same ID parameter. A good solution would be define a parameter name which will point to the desired language, say
params[:lang]
, then as I showed in the previous article, you can use it in your application controller to switch the locale by a before filter.
class ApplicationController < ActionController::Base
init_gettext 'my_site'
before_filter :define_language
def define_language
case params[:lang]
when 'fr': set_locale 'fr_FR'
when 'ru': set_locale 'ru_RU'
else set_locale 'en_EN'
end
end
end
and then you left some options for youself how present it at your urls. You may use a simplest way like and left the gings as is
/articles/show/1 <- English
/articles/show/1?lang=fr <- French
or you can handle the language by routes so your pages were more caching friendly
map.connect ':controller/:action/:id'
map.connect ':lang/:controller/:action/:id',
:requirements => {
:lang => /(ru|de|fr)/
}, :lang => nil
----
/articles/show/1 <- English
/fr/articles/show/1 <- French
or later you may handle them by subdomains or something like that, whatever you choose your application code will not need changes.
--
Okay, think that is all what I had to say about using gettext with rails. Good luck!
Friday, July 18, 2008
Rails + Gettext Crash Course, Part 1
This article is a short guide to how use gettext with ruby-on-rails. If you do not know gettext is the standard internationalisation (i18n) library of the GNU project http://en.wikipedia.org/wiki/Gettext. And this is the first part of the two articles. The second one might be found here.
Since there are some of i18n plugins for rails why should you chose gettext?
For some reasons.
First as I said it is the standard for GNU. Standard means wide support several tools to work with it, optimisation, documentation, etc. Most of Linux programmes use gettext.
Second, one of the key features of gettext is ability to use real, correct strings. You don't write strange keys in your code, you just put usual English phrases instead, like that
As you see this allows you easily use any placeholders or html formatting tags in here if you need so. Another point for gettext is that you don't have to keep in mind the translation issues during the development time. You just put your text as nothing happened and always have a default translation with normal usual looking strings.
After you have done with the development you can parse out all the strings which need to be translated with special util. You will have standard formed .po file which you can then translate with some special programs, where you can use spellchecking versioning and all the civilize life advantages.
Third, this stuff can do lots of things, localize numbers, dates, currencies, work with pluralization on native languages and so one. Take a look at the official site for getting more information http://www.gnu.org/software/gettext/gettext.html
So how do we use the stuff with rails?
Quite simple.
First of all you need to install gettext by itself and rubysupport aka gem. Installation of gettext depends on your platform. With linux it's pretty simple. Say something like
Once you have installed gettext support, you need to install the gettext gem.
After it is done, you need to include it into
After this you can start develop your project and use the
If you are using Rails 2.1, there's a bug which have not fixed yet. But you can easily fix it by saving the following code into a file
Once you have done with the development and want to create some translation you need to do some preparations.
First you need to add two simple tasks to your Rakefile.
The first one will scan though your source code and parse out all the strings which need to be translated and put them all into a .po file. The second one will compile all your translations into a standard .mo files which gettext can use.
So, you say 'rake updatepo' in your console and this will create for you the file named 'po/my_site.pot', this is template of your internationalisation. You copy the file in translation directories like that.
Then you translate the .po files with one of the translation programmes, say this one http://www.poedit.net. Under Linux and KDE you can use standard KBabel programme, or under Gnome you can use the gtrasnlator project. Certainly you can edit those files just as plain text if you like so. Many texteditors support them.
Once you have done with the translation, run the 'rake makemo' task in your console and it will create the 'locale' directory in your rails project folder with a standard structure like that
This is almost it. You only need to initiate it in your application controller now.
As you see we have used non existing locale 'en_EN', if there is no some locale your default strings from the source code will be used. So you always have a fallback language.
This is pretty much it for the start.
But remember with gettext you not only put some translated text-labels in your application, you easily can create translations of whole template files, you can translate models, values, format numbers, dates and do lot of another useful things.
Since there are some of i18n plugins for rails why should you chose gettext?
For some reasons.
First as I said it is the standard for GNU. Standard means wide support several tools to work with it, optimisation, documentation, etc. Most of Linux programmes use gettext.
Second, one of the key features of gettext is ability to use real, correct strings. You don't write strange keys in your code, you just put usual English phrases instead, like that
<p><%= _('Some text here') %></p>
<p><%= _('Length: <i>(%{min} min)</i>') % { :min => @min_chars } %></p>
As you see this allows you easily use any placeholders or html formatting tags in here if you need so. Another point for gettext is that you don't have to keep in mind the translation issues during the development time. You just put your text as nothing happened and always have a default translation with normal usual looking strings.
After you have done with the development you can parse out all the strings which need to be translated with special util. You will have standard formed .po file which you can then translate with some special programs, where you can use spellchecking versioning and all the civilize life advantages.
Third, this stuff can do lots of things, localize numbers, dates, currencies, work with pluralization on native languages and so one. Take a look at the official site for getting more information http://www.gnu.org/software/gettext/gettext.html
So how do we use the stuff with rails?
Quite simple.
First of all you need to install gettext by itself and rubysupport aka gem. Installation of gettext depends on your platform. With linux it's pretty simple. Say something like
# emerge gettext
or
# apt-get install gettext
Once you have installed gettext support, you need to install the gettext gem.
# gem install gettext
After it is done, you need to include it into
config/environment.rb
file of your rails project.
require 'gettext/rails'
After this you can start develop your project and use the
_('text')
constructions where you need to put some text.If you are using Rails 2.1, there's a bug which have not fixed yet. But you can easily fix it by saving the following code into a file
config/initializers/gettext.rb
# the gettext missed method fix
module ActionView
class Base
delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
end
end
Once you have done with the development and want to create some translation you need to do some preparations.
First you need to add two simple tasks to your Rakefile.
require 'gettext/utils'
desc "Update pot/po files to match new version."
task :updatepo do
GetText.update_pofiles(
"my_site",
Dir.glob("{app,lib}/**/*.{rb,rhtml,erb,rjs}"),
"my_site version"
)
end
desc "Create mo-files for L10n"
task :makemo do
GetText.create_mofiles(true, "po", "locale")
end
The first one will scan though your source code and parse out all the strings which need to be translated and put them all into a .po file. The second one will compile all your translations into a standard .mo files which gettext can use.
So, you say 'rake updatepo' in your console and this will create for you the file named 'po/my_site.pot', this is template of your internationalisation. You copy the file in translation directories like that.
po/
de_DE/my_site.po
fr_FR/my_site.po
ru_RU/my_site.po
my_site.pot
Then you translate the .po files with one of the translation programmes, say this one http://www.poedit.net. Under Linux and KDE you can use standard KBabel programme, or under Gnome you can use the gtrasnlator project. Certainly you can edit those files just as plain text if you like so. Many texteditors support them.
Once you have done with the translation, run the 'rake makemo' task in your console and it will create the 'locale' directory in your rails project folder with a standard structure like that
locale/
de_DE/LC_MESSAGES/my_site.mo
fr_FR/LC_MESSAGES/my_site.mo
ru_RU/LC_MESSAGES/my_site.mo
This is almost it. You only need to initiate it in your application controller now.
class ApplicationController < ActionController::Base
GetText.locale = 'en_EN' # <- default locale
init_gettext 'my_site'
before_filter :define_language
def define_language
# here you can switch the locale on fly
# say like that
case params[:lang]
when 'de': set_locale 'de_DE'
when 'fr': set_locale 'fr_FR'
when 'ru': set_locale 'ru_RU'
else set_locale 'en_EN'
end
end
end
As you see we have used non existing locale 'en_EN', if there is no some locale your default strings from the source code will be used. So you always have a fallback language.
This is pretty much it for the start.
But remember with gettext you not only put some translated text-labels in your application, you easily can create translations of whole template files, you can translate models, values, format numbers, dates and do lot of another useful things.
Thursday, July 3, 2008
TestCase 2.0 is out
After several month of development, finally I have released the tool version 2.0
There is the release notes and short changelog
Download page
And now you can watch the project's demo
There is the release notes and short changelog
Download page
And now you can watch the project's demo
Saturday, June 28, 2008
Making Quicktime work in Ubuntu
There is a common issue with quicktime videostreams under linux. So this is a simple trick how you can make it working under the Ubuntu linux.
1) Uninstall all the video plugins you have got with your firefox installation (for example the vlc plugin)
2) Install the mplayer package and the quicktime extentions for it.
3) Install the mozilla-mplayer plugin
4) Reinstall firefox.
That's it. Go to apple.com/trailers, it should get working now
1) Uninstall all the video plugins you have got with your firefox installation (for example the vlc plugin)
2) Install the mplayer package and the quicktime extentions for it.
3) Install the mozilla-mplayer plugin
4) Reinstall firefox.
That's it. Go to apple.com/trailers, it should get working now
Monday, June 16, 2008
JavaScript Diff Function Implementation
Since I have not ever done it before, I have found it was not obvious to me how to create a lists diff function in JavaScript, so I feel like should public the solution.
this function will return a sequention of hashes with keys 'minus', 'plus', 'same' which represents the differences and similarities between the two incomming arrays
function diff(first, second) {
var diff = [], start_k = 0;
// calculating the diff
for (var i=0; i < first.length; i++) {
var same_found = false;
var pluses = [];
for (var k=start_k; k < second.length; k++) {
if (first[i] == second[k]) {
same_found = second[k];
start_k = k+1;
break;
} else {
pluses.push(second[k]);
}
}
if (same_found) {
for (var j=0; j < pluses.length; j++) {
diff.push({plus: pluses[j]});
}
diff.push({same: same_found});
} else {
diff.push({minus: first[i]});
}
}
// pushing down the trailing elements
for (var k=start_k; k < second.length; k++) {
diff.push({plus: second[k]});
}
return diff;
};
this function will return a sequention of hashes with keys 'minus', 'plus', 'same' which represents the differences and similarities between the two incomming arrays
Wednesday, May 14, 2008
Tried KDE4 on Kubuntu
I've been testing Kubuntu with KDE4 today and have learnt two lessons.
1) There's nothing to be eager about KDE4. I mean, seriously, the guys do a good job, but this is still the same good old kde3. Those plasma and dolphin stuffs, doesn't change much, that's like a good version of the superkaramba project, it looks nice but practically doesn't change the workflow at all. And as 99% of applications still from KDE3, if don't mention internal changes, in really you've got a new nice theme for kde.
I'm little bit disappointed, the fourth version was anounced for good couple of years ago and then been delayed several times and as the result we've got something pretty raw and almost nothing new.
Yup, that's it, there's nothing in really why you should migrate to kde4 so far.
2) The quality of kubuntu is lower then the quality of ubuntu. Sorry gus, but that's true. There are several things which works out of box in ubuntu, but doesn't work in kubuntu. Several things are left behind in order to keep the kde-purity, that left a bad feeling.
1) There's nothing to be eager about KDE4. I mean, seriously, the guys do a good job, but this is still the same good old kde3. Those plasma and dolphin stuffs, doesn't change much, that's like a good version of the superkaramba project, it looks nice but practically doesn't change the workflow at all. And as 99% of applications still from KDE3, if don't mention internal changes, in really you've got a new nice theme for kde.
I'm little bit disappointed, the fourth version was anounced for good couple of years ago and then been delayed several times and as the result we've got something pretty raw and almost nothing new.
Yup, that's it, there's nothing in really why you should migrate to kde4 so far.
2) The quality of kubuntu is lower then the quality of ubuntu. Sorry gus, but that's true. There are several things which works out of box in ubuntu, but doesn't work in kubuntu. Several things are left behind in order to keep the kde-purity, that left a bad feeling.
Monday, May 5, 2008
Order By Aggregations With ActiveRecord
The issue is following, say you have got a classical structure in two models
As you see the orders don't have own total_due fields, instead of this each order can calculate the value depend on the aggregated items. So, that's cool, we follow all the good design habits and keep the things clean.
But when you retrieve/display the orders list there might be a situation when a customer would like to order the list by the total_due value. Quite a natural desire, but there's the problem, we don't have the total_due field in really. It's virtual and depend on the aggregated objects.
Yes, you may reorder the items after retrieving, manually, but if you have quite a lot of orders and use a pagination you'll get back to the problem anyway.
The example is pretty simple, but you see, there might be lots of similar situations when you have some calculations on an aggregated data and would like to order your lists depends on the virtual fields.
So, how do we handle that?
We use the :select option for the ActiveRecord find method. Usually with the option you specify a number of fields you would like to extract, to not suck up heavy ones when you don't want them. But with the same option you may specify additional fields to extract and use all the power of SQL expressions. Those new fields will be added to the instanced object temporary, you can read them but you can't save them.
In our case this might be something like that
In the case we are using the SQL function SUM, calculate the total-due for each order, and then each selected order will obtain the total_due attribute after extraction and you may use it for your sorting options.
Then, as you see we mentioned the 'order_items' column in the select option, to make it working we should add a tables join and the items grouping options. The overall instruction might look like that.
After this you will need to fix your Order model a little, to make it use the temporary field when it appears
Yes, that looks a little bit sqlish dirty for a rails application, but then it works and does what you need.
And there's another issue with the solution. You actually cannot use the :include option with the :select option at the same time. That's usually not a big issue, just note, if you specify the :include option, your :select option won't work.
class Order < ActiveRecord::Base
has_many order_items
def total_due
order_items.to_a.sum(&:total_price)
end
end
class OrderItem < ActiveRecord::Base
belongs_to :order
# and it has two principal fields
# decimal :price
# integer :quantity
def total_price
price * quantity
end
end
As you see the orders don't have own total_due fields, instead of this each order can calculate the value depend on the aggregated items. So, that's cool, we follow all the good design habits and keep the things clean.
But when you retrieve/display the orders list there might be a situation when a customer would like to order the list by the total_due value. Quite a natural desire, but there's the problem, we don't have the total_due field in really. It's virtual and depend on the aggregated objects.
Yes, you may reorder the items after retrieving, manually, but if you have quite a lot of orders and use a pagination you'll get back to the problem anyway.
The example is pretty simple, but you see, there might be lots of similar situations when you have some calculations on an aggregated data and would like to order your lists depends on the virtual fields.
So, how do we handle that?
We use the :select option for the ActiveRecord find method. Usually with the option you specify a number of fields you would like to extract, to not suck up heavy ones when you don't want them. But with the same option you may specify additional fields to extract and use all the power of SQL expressions. Those new fields will be added to the instanced object temporary, you can read them but you can't save them.
In our case this might be something like that
:select => "SUM(order_items.price * order_items.quantity) as total_due"
In the case we are using the SQL function SUM, calculate the total-due for each order, and then each selected order will obtain the total_due attribute after extraction and you may use it for your sorting options.
Then, as you see we mentioned the 'order_items' column in the select option, to make it working we should add a tables join and the items grouping options. The overall instruction might look like that.
Order.find(:all,
:select => "SUM(order_items.price * order_items.quantity) as total_due, orders.*",
:joins => "INNER JOIN order_items ON order.id = order_items.order_id",
:group => "order.id",
:order => "total_due"
)
After this you will need to fix your Order model a little, to make it use the temporary field when it appears
class Order < ActiveRecord::Base
def total_due
self[:total_due] || order_items.to_a.sub(&:total_price)
end
end
Yes, that looks a little bit sqlish dirty for a rails application, but then it works and does what you need.
And there's another issue with the solution. You actually cannot use the :include option with the :select option at the same time. That's usually not a big issue, just note, if you specify the :include option, your :select option won't work.
Friday, April 18, 2008
I think stories need chapters
This rspec's stories stuff is quite nice, I like it. But when I'm trying to write more or less complex story it turns out to a nightmare. It's quite hard to stay on the DRY way with the stories, you always need to repeat the stuffs again and again. Even if you organize your code in good and handy steps, you'll have to repeat them in the scenarios anyway.
So, I think it would be cool to have in the stories another level aka Chapter. Think even nested chapters. I could look like that.
The idea is that the chapters were working like scopes for the inside subchapters and scenarios. You may specify there common givens and thens which will be applied to the internal parts. May be it could be useful to be able to attach additional steps for particular chapters.
So, I think it would be cool to have in the stories another level aka Chapter. Think even nested chapters. I could look like that.
Story "an item live-story" do
Chapter "items index" do
Given "two items"
Scenario "anonymous gets the index" do
Given "an anonymous user"
When "he GET /items"
Then "he should be redirected to the login_path"
end
Scenario "registered user gets the index" do
Given "a logged in user"
When "he GET /items"
Then "he should see the 'items/index' page"
And "both items should be on the page"
end
Then "something in common happens"
end
end
The idea is that the chapters were working like scopes for the inside subchapters and scenarios. You may specify there common givens and thens which will be applied to the internal parts. May be it could be useful to be able to attach additional steps for particular chapters.
Wednesday, April 16, 2008
Ajaxload - The Spinners Generator
Found today the resource ajaxload.info, you can generate your custom ajaxload spinners there.
The guys did pretty well I should say. There are lots of patterns, you can choose a transparent background and custom colors.
Nice stuff.
The guys did pretty well I should say. There are lots of patterns, you can choose a transparent background and custom colors.
Nice stuff.
Tuesday, April 15, 2008
Displaying GIT Branch Name In Your Console
So, if you had been taken the gateway drug of GIT recently, then you probably feel the sake of branches and there's a little trick for you dear fellow.
Put (or change) the following stings in your ~/.bashrc file and you'll get a nice enhancement on your console prompt which will show your current git-branch when you're in a directory which is under git.
This is quite handy when you use the branches feature actively.
Put (or change) the following stings in your ~/.bashrc file and you'll get a nice enhancement on your console prompt which will show your current git-branch when you're in a directory which is under git.
function git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
PS1='\[\033[0;37m\][\[\033[01;36m\]\W\[\033[0;37m\]] \[\033[0;32m\]$(git_branch)\[\033[00m\]\$ '
This is quite handy when you use the branches feature actively.
Sunday, April 13, 2008
Rescue data from a reiserfs partition
Couple of days ago, I met a situation, when my /home partition, which was on reiserfs filesystem, all the sudden, got dead. It was not able to restore the partition with reiserfs utils, it didn't want to mount anymore, info said there only 563 Kb of 60 Gb data left. Not good.
I've spent a day rescuing the data, and managed to get back 99% of it (i belive), so now I share the experience.
The rule number one in such a situation is to calm down. Sit down, take a blank sheet of paper, a pencil and then in a nice friendly characters write the phrase "DON'T PANIC".
I'm serious, it's pretty easy to get jumpy and overreactive when "all of yours" suddenly getting disappeared. And surrely it's easy to broke something down completely. So, don't touch anything until you get back to the cool consciousness.
The second thing you need, is a complete copy of your damaged partition. For that you'll need another free partition with exact same size. If you have such space on another hard drive, create it there, or think about baying another one.
Once you have your new partition for the backup. You need to boot up on some kind of live-cd with a linux environment. I've used the ubuntu 7.10 live-cd, it's quite handy, understand most of the modern hardware, contains the gparted util, have a web-browser etc. So it's stuffed pretty good for our purpose.
When you have your live cd booted up, you may copy the partitions. There's a builtin prgramm called 'dd', which allows you to copy block devices byte by byte, one to another. So you run it like that.
Where the '/dev/old' and '/dev/new' are your damaged and backup partitions. The optional attribute 'conv=noerror' tells the commad to skip reading errors.
Optionally you may unlock the 'universe' repository and install the 'dd_rescue' prgramm, which I belive, a wrapper for the 'dd' command and provides some more resuce oriended functionality.
The main point is to create an exact copy of the aviable data from the damaged partition.
And note, depends on the conditions, this may take quite a long time. My 60G partition was copied in about 7 hours.
That's it. Once you have a copy block. You run the 'reiserfsck' on the _copy_ partition like that.
Note the '-S' option. This tells the reiserfsck programm to scan the whole partition for the aviable data. It's important, don't miss it up.
This operation usually is quite fast. Depends on the size of your data, and its condition this will take some minutes.
After the reiserfsck pargamm have finished, mount your new partition and take a look how is it going. If your partition was not damaged too hard, most of the data and directories structure will be on the right places. And there will be the 'lost+found' directory, take a look in it too, there will be lots of directories and subdirectories named with numbers. The util put there the files which were recovered but which former place was not found. And you may find there some files which you have deleted recently. So browse throw the directories, you may find some valuable data there too.
This is pretty much it. In really it's qute a simple stuff. Just don't get scary, some bad blocks on your hard drive is not a big problem, most of your data usually safe untill the harddrive any-working.
I've spent a day rescuing the data, and managed to get back 99% of it (i belive), so now I share the experience.
The rule number one in such a situation is to calm down. Sit down, take a blank sheet of paper, a pencil and then in a nice friendly characters write the phrase "DON'T PANIC".
I'm serious, it's pretty easy to get jumpy and overreactive when "all of yours" suddenly getting disappeared. And surrely it's easy to broke something down completely. So, don't touch anything until you get back to the cool consciousness.
The second thing you need, is a complete copy of your damaged partition. For that you'll need another free partition with exact same size. If you have such space on another hard drive, create it there, or think about baying another one.
Once you have your new partition for the backup. You need to boot up on some kind of live-cd with a linux environment. I've used the ubuntu 7.10 live-cd, it's quite handy, understand most of the modern hardware, contains the gparted util, have a web-browser etc. So it's stuffed pretty good for our purpose.
When you have your live cd booted up, you may copy the partitions. There's a builtin prgramm called 'dd', which allows you to copy block devices byte by byte, one to another. So you run it like that.
$ sudo dd conv=noerror if=/dev/old of=/dev/new
Where the '/dev/old' and '/dev/new' are your damaged and backup partitions. The optional attribute 'conv=noerror' tells the commad to skip reading errors.
Optionally you may unlock the 'universe' repository and install the 'dd_rescue' prgramm, which I belive, a wrapper for the 'dd' command and provides some more resuce oriended functionality.
The main point is to create an exact copy of the aviable data from the damaged partition.
And note, depends on the conditions, this may take quite a long time. My 60G partition was copied in about 7 hours.
That's it. Once you have a copy block. You run the 'reiserfsck' on the _copy_ partition like that.
$ sudo reiserfsck --rebuild-tree -S /dev/new
Note the '-S' option. This tells the reiserfsck programm to scan the whole partition for the aviable data. It's important, don't miss it up.
This operation usually is quite fast. Depends on the size of your data, and its condition this will take some minutes.
After the reiserfsck pargamm have finished, mount your new partition and take a look how is it going. If your partition was not damaged too hard, most of the data and directories structure will be on the right places. And there will be the 'lost+found' directory, take a look in it too, there will be lots of directories and subdirectories named with numbers. The util put there the files which were recovered but which former place was not found. And you may find there some files which you have deleted recently. So browse throw the directories, you may find some valuable data there too.
This is pretty much it. In really it's qute a simple stuff. Just don't get scary, some bad blocks on your hard drive is not a big problem, most of your data usually safe untill the harddrive any-working.
Sunday, April 6, 2008
Wish that thing in Ruby
class Array
def ||<<(i)
<< i unless include? i
end
end
Think, that would be logically appropriate, in similar to the ||= operation
Sunday, March 30, 2008
Idea about restful_authentication plugin
If you're using the restful_authentication plugin with your rails projects, there's a simple idea which might be interesting to you.
Idea as I said pretty simple. Rename the users_controller which the plugin generates to profiles_controller, and sequentially change the routes declaration
The reason is simple as well. With the controller you actually manage the user's profile (the registration process for example), not the users collection in really. For administration purposes you may need more standard CRUD controller for the User unit later. And you will extend the existing controller, then you may run into some ugly constructions in it pretty soon.
But with such a simple renaming you'll keep the things more clear and reusable.
Idea as I said pretty simple. Rename the users_controller which the plugin generates to profiles_controller, and sequentially change the routes declaration
# from
map.resources :users
# to
map.resource :profile
The reason is simple as well. With the controller you actually manage the user's profile (the registration process for example), not the users collection in really. For administration purposes you may need more standard CRUD controller for the User unit later. And you will extend the existing controller, then you may run into some ugly constructions in it pretty soon.
But with such a simple renaming you'll keep the things more clear and reusable.
Tuesday, March 25, 2008
Another Work Is Done
With love and proud another piece of work been done and now on the air.
Met http://www.redstarpoker.com! Some pretty basic but loverly done rails work.
And don't blame me on the main menu with images, that's all the communists, they like such stuffs.
Met http://www.redstarpoker.com! Some pretty basic but loverly done rails work.
And don't blame me on the main menu with images, that's all the communists, they like such stuffs.
Monday, March 24, 2008
Creating element event handlers with RJS
If you're working with rails and ajax you probably familiar with the
So, that's cool. But sometimes you might want to use RJS to write some events handling for say a form element. For example you've got a select box which switches different blocks on/off depends on what you choose and you need to wire the 'onchange' event with some logic. In a such case you can pass the :onchange value of the html_options argument in the 'select' helper method. The problem is that it applies a string, not a block where you can put in your RJS stuffs.
And the problem is solvable. There's another helper method which actually applies a block of rjs code and returns a string of compiled javascript code. It's name
it's a little bit hacky, I've used this 'page << ' stuff and it's not probably a good rjs example. But I want to show the idea only. Whenever you need a javascript string and wish to write it in RJS, you can use the 'update_page' method and have it on.
link_to_function
helper. And especially with its ability to apply a block where you can put some RJS code. Sometimes it's pretty handy. Especially if you're not much javascript guru or just don't want to get dirty with it.So, that's cool. But sometimes you might want to use RJS to write some events handling for say a form element. For example you've got a select box which switches different blocks on/off depends on what you choose and you need to wire the 'onchange' event with some logic. In a such case you can pass the :onchange value of the html_options argument in the 'select' helper method. The problem is that it applies a string, not a block where you can put in your RJS stuffs.
And the problem is solvable. There's another helper method which actually applies a block of rjs code and returns a string of compiled javascript code. It's name
update_page
. The link_to_function
method calls it internally. For example you want to switch some blocks depend on a chosen language. This might look like that.
<%= select nil, nil, Language.to_options, {}, :onchange => update_page{ |page|
Language.all.each do |lang|
page << %{$("block-in-langage-#{lang.id}")[this.value == '#{lang.id}' ? 'show' : 'hide']();}
end
} %>
it's a little bit hacky, I've used this 'page << ' stuff and it's not probably a good rjs example. But I want to show the idea only. Whenever you need a javascript string and wish to write it in RJS, you can use the 'update_page' method and have it on.
Friday, March 21, 2008
How to define the pages-cache directory onfly
Generally, in Rails, when you have a deal with the page-cache feature, you define the cache output directory (if define at all) in the environment.rb, something like that
But sometimes you may need to add something special to the path on fly, when the controller is working. Say a language prefix or so. And you can do so in a nice one-line patch. You should overload the 'cache_page' method (not the 'caches_page' one), like that
And you won't need to touch anything else, case all your controller caching settings will eventually call the method. Just notice, that the method should be public. And don't forget to add your hacky prefix to your sweepers.
That's pretty much it.
config.action_controller.page_cache_directory = RAILS_ROOT + "/public/cache/"
But sometimes you may need to add something special to the path on fly, when the controller is working. Say a language prefix or so. And you can do so in a nice one-line patch. You should overload the 'cache_page' method (not the 'caches_page' one), like that
def cache_page(content=nil, path=nil)
super content || response.body, path || (@language_name + request.path)
end
And you won't need to touch anything else, case all your controller caching settings will eventually call the method. Just notice, that the method should be public. And don't forget to add your hacky prefix to your sweepers.
That's pretty much it.
How to setup updated_at field manually
There's a simple case. Say I've got a model which logic depends on the magic updated_at field and I would like to test it. But the question is how to set the value manually up, when you need it? If you try something like
Then you'll have your updated_at field set to Time.now whatever you pass in it, because ActiveRecord will overwrite it by default.
The answer is simple, use the 'record_timestamps=' class-method which switches on/off the automatic updating of the created and updated fields.
That's it.
@article.update_attributes :updated_at => 10.minutes.ago
Then you'll have your updated_at field set to Time.now whatever you pass in it, because ActiveRecord will overwrite it by default.
The answer is simple, use the 'record_timestamps=' class-method which switches on/off the automatic updating of the created and updated fields.
Article.record_timestamps = false
@article.update_attributes :updated_at => 10.minutes.ago
Article.record_timestamps = true
That's it.
Monday, March 17, 2008
Single Table Inheritance With Nested Classes in Rails
There's a feature in Rails, which allows you to have several classes on the same table. You define a string column named 'type' and then inherit your new classes from the basic unit class. Pretty simple and sometimes very useful. It's called Single Table Inheritance or simply STI.
But in some cases there are might be quite a number of subclasses and you may even don't know how many of them will be. Say a simple case. You've got a class Game which presents a basic game model data-structure, and then you've got several subclasses which represents real games logic which have just the same data-structure but different behavior. The customer said I want those five games now and probable another good five later.
Ok, that's fine and probably an excellent opportunity for using the STI feature. But the thing which bothers me in the case is the big and unpredictable number of subclasses, and as for me, I would like to not have such a mess in my app/model/ directory.
A possible solution is in having nested subclasses for the Game class. In general it might look like this
Then, when you create instances of the subclasses you'll have the 'type' attribute set properly to the name of the subclass.
This will work just the same way if would define a usual class like
and then inside, say, the poker.rb file define your nested classes like that
In such a way you'll keep your subclasses organized well and still will be able to use the STI feature.
But in some cases there are might be quite a number of subclasses and you may even don't know how many of them will be. Say a simple case. You've got a class Game which presents a basic game model data-structure, and then you've got several subclasses which represents real games logic which have just the same data-structure but different behavior. The customer said I want those five games now and probable another good five later.
Ok, that's fine and probably an excellent opportunity for using the STI feature. But the thing which bothers me in the case is the big and unpredictable number of subclasses, and as for me, I would like to not have such a mess in my app/model/ directory.
A possible solution is in having nested subclasses for the Game class. In general it might look like this
class Game < ActiveRecord::Base
#........ some basic crap .........
class Klondike < Game
end
class Poker < Game
end
end
Then, when you create instances of the subclasses you'll have the 'type' attribute set properly to the name of the subclass.
>> g = Game::Poker.new
>> g
=> #<Game::Poker type: "Poker", ....>
This will work just the same way if would define a usual class like
class PokerGame < Game
, but this solution with nested classes allows you to organize your subclasses better. Now you can, by following the rails naming convention, create the following directories/files structure
app/
models/
game/
klondike.rb
poker.rb
game.rb
and then inside, say, the poker.rb file define your nested classes like that
class Game::Poker < Game
....
end
In such a way you'll keep your subclasses organized well and still will be able to use the STI feature.
Thursday, March 13, 2008
Story Writing Is Fun
This is about the Story Framework, which is a part of the RSpec library. There's no documentation for the stuff on the official site and very few articles over the Internet, so I think one more example won't hurt, at last it's a really awesome tool.
Generally, Story Writing is a part of BDD, which allows you to define the scope of a system feature along with the criteria of the feature acceptance. If simple and basically, then Stories for BDD are about the same as integration tests for TDD. In case of Rails, this will be RSpec's replacement for the rails native integration tests. The general difference is that it based on the RSpec's expectations. Terrific and fun replacement I should say. 8)
So, lets get down to the deal. My goal for now is to display how a general story should look like and what can you do with it. And because I'm not going to display the stories based development process in action, I'll break the very first rule, precisely "test first". But don't get fooled, in general story writing is a part of BDD process, and in a correct sequence you are writing story first, then you write your specs and code. I just want to show an average story by itself.
Ok, lets assume we have got a rails project, with the rspec and rspec_on_rails plugins installed. Then assume you've generated an Article model rspec_scaffold, then you have installed the restful_authentication plugin and generated the whole user's stuffs. Those are pretty much standard actions, so I won't stop on them here.
First of all you should check your specs and get sure that all of them are happy. Here you should understand the difference between the sepcs and stories. Your specs describes the system objects behavior, this is an equivalent of unit-tests. Stories describes how a whole system (or its aspect) behaves in certain situations. So, writing stories don't forget about your specs, that's your backup and this is not a bad idea to keep the autotest util runned on somewhere in background.
Each story for a first sight might look like something free but they have a particular format. Each story contains one or more scenarios and each scenario describes a particular situation in a simple form setting -> action -> result. Something like that
This is a pretty basic example, just to show common Story structure. As you see this is a piece of ruby code, you calls something, put in it variables and blocks. You even my execute the code if you write it in a file. But now you should notice the three blocks
Each of the blocks in really applies additional variables and blocks, the string you passing in is a name of the step. As the story doesn't have any implementation in it, if you have it executed, all the blocks will be marked as "pending".
Ok, this is pretty much it. Lets now write something more meaningful. Say we want that all registered and anonymous users could see the articles index. So we are writing a story.
As you see we are using the RSpec expectations syntactics and doing some activities inside the blocks. You may add more
More interesting the second scenario, especially this part
If you have executed the story, you won't see any pending elements, everything will be executed. And there's the tricky point. Each step you fill up with code will be saved inside a story as a method and might later be called by the name you have specified. And sure you can specify arguments for a step. See the case with the When step. In the second call instead of the articles_path could be any path and it would be used inside the block specified in the first scenario but executed in the scope of the second scenario.
Okay, that's nice. But if then we want to write another story, for the "show" action. You don't need to be a master-mind to figure out that this will be a pretty much similar one. Wanna your DRY for the case? No problem, you can extract the steps out of stories at all and create a steps collection. Like that.
You might put the code inside the stories/helper.rb file or inside a separated file and require it, or just put above your story and then write your stories like that:
Surely it looks much more readable and still will be executed and do what you need. And there's another trick I haven't mentioned. This piece of code
Inside the steps definition. This magic construction "$page_name" will parse out the template name right out of the passed step name and put it into the block. Therefore you can write your steps like
The same step will be involved, but first time with the 'index' page_name, and the second with the 'show' page_name.
This way you can define your own small macro-language to describe your system behavior with short and easy to understand phrases. You even might show the stuff to your customer and he will understand what's going on and will be sure that the system is doing what he need.
And this is not the end again. As you probably noticed, that after you have moved all the steps code into a standalone class, your story contains nothing but text. In such case you can even go further and put your stories in a plain text. In a such format
Isn't that great? You can save that text in a file and then execute it with a simple runner, similar to this one.
You may have one script for all of your textual stories it's up to you. And you'll need to change a little your When step to be like
That's it. If you ever written integration tests with the native rails integration tests framework, you probably noticed how ugly and complex they tend to become when the application logic gets serious. So the Story Framework of RSpec offers you an excellent opportunity to change the things for better. With stories you can easily organize your system behavior description in collections of simple scenarios and inside each scenario you can easily set up the necessary conditions, run necessary actions and check the result. And that more important you can do in a very simple way, just with few short strings which anyone can understand.
That's what I wanted to show today.
So long and write the stories it's fun! ;)
Generally, Story Writing is a part of BDD, which allows you to define the scope of a system feature along with the criteria of the feature acceptance. If simple and basically, then Stories for BDD are about the same as integration tests for TDD. In case of Rails, this will be RSpec's replacement for the rails native integration tests. The general difference is that it based on the RSpec's expectations. Terrific and fun replacement I should say. 8)
So, lets get down to the deal. My goal for now is to display how a general story should look like and what can you do with it. And because I'm not going to display the stories based development process in action, I'll break the very first rule, precisely "test first". But don't get fooled, in general story writing is a part of BDD process, and in a correct sequence you are writing story first, then you write your specs and code. I just want to show an average story by itself.
Ok, lets assume we have got a rails project, with the rspec and rspec_on_rails plugins installed. Then assume you've generated an Article model rspec_scaffold, then you have installed the restful_authentication plugin and generated the whole user's stuffs. Those are pretty much standard actions, so I won't stop on them here.
First of all you should check your specs and get sure that all of them are happy. Here you should understand the difference between the sepcs and stories. Your specs describes the system objects behavior, this is an equivalent of unit-tests. Stories describes how a whole system (or its aspect) behaves in certain situations. So, writing stories don't forget about your specs, that's your backup and this is not a bad idea to keep the autotest util runned on somewhere in background.
Each story for a first sight might look like something free but they have a particular format. Each story contains one or more scenarios and each scenario describes a particular situation in a simple form setting -> action -> result. Something like that
Story "name", "description" do
Scenario "short descritpion" do
Given "something"
And "something else"
And "maybe something more"
When "I do something"
Then "the system will produce that"
And "it should do that also"
And "probably this one should get happened too"
end
Scenario "..."
end
This is a pretty basic example, just to show common Story structure. As you see this is a piece of ruby code, you calls something, put in it variables and blocks. You even my execute the code if you write it in a file. But now you should notice the three blocks
- Given [And, And...] - describes the action setting
- When - describes the action
- Then [And, And...] - describes the action results
Each of the blocks in really applies additional variables and blocks, the string you passing in is a name of the step. As the story doesn't have any implementation in it, if you have it executed, all the blocks will be marked as "pending".
Ok, this is pretty much it. Lets now write something more meaningful. Say we want that all registered and anonymous users could see the articles index. So we are writing a story.
Story "articles browsing", %{
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles
}, :type => RailsStory do
Scenario "anonymous user gets the index" do
Given "an article" do
@article = Article.new
@article.stub!(:valid?).and_return(true)
@article.save
end
When "I get to the page", articles_path do |path|
get path
end
Then "I see the index" do
response.should render_template('index')
end
end
Scenario "registered user gets the index" do
Given "logged in user" do
@user = User.new :login => 'asdf', :password => 'asdf'
@user.stub!(:valid?).and_return(true)
@user.save
post sessions_path :login => @user.login, :password => @user.password
end
And "an article"
When "I get to the page", articles_path
Then "I see the index"
end
end
As you see we are using the RSpec expectations syntactics and doing some activities inside the blocks. You may add more
And "..." do; end
blocks into your Then description and describe more result criteria you would need to check out. And you can use just the same RSpec tools as inside your controller specs.More interesting the second scenario, especially this part
And "an article"
When "I get to the page", articles_path
Then "I see the index"
If you have executed the story, you won't see any pending elements, everything will be executed. And there's the tricky point. Each step you fill up with code will be saved inside a story as a method and might later be called by the name you have specified. And sure you can specify arguments for a step. See the case with the When step. In the second call instead of the articles_path could be any path and it would be used inside the block specified in the first scenario but executed in the scope of the second scenario.
Okay, that's nice. But if then we want to write another story, for the "show" action. You don't need to be a master-mind to figure out that this will be a pretty much similar one. Wanna your DRY for the case? No problem, you can extract the steps out of stories at all and create a steps collection. Like that.
class ArticlesAccessSteps < < Spec::Story::StepGroup
steps do |define|
define.given "an article" do
@article = Article.new
@article.stub!(:valid?).and_return(true)
@article.save
end
define.given "logged in user" do
@user = User.new :login => 'asdf', :password => 'asdf'
@user.stub!(:valid?).and_return(true)
@user.save
post sessions_path :login => @user.login, :password => @user.password
end
define.when "I GET the page" do |path|
get path
end
define.then "I see the $page_name" do |page_name|
response.should render_template(page_name)
end
end
end
You might put the code inside the stories/helper.rb file or inside a separated file and require it, or just put above your story and then write your stories like that:
Story "articles browsing", %{
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles
}, :type => RailsStory, :steps => ArticlesAccessSteps.new do # <- watch out the ':steps =>' attribute
Scenario "anonymous user gets the index" do
Given "an article"
When "I GET the page", articles_path
Then "I see the index"
end
Scenario "registered user gets the index" do
Given "logged in 'user'"
And "an article"
When "I GET the page", articles_path
Then "I see the index"
end
end
Story "article displaying", :type => RailsStory, :steps => ArticlesAccessSteps.new do
Scenario "anonymous user gets the index" do
Given "an article"
When "I GET the page", article_path(@article)
Then "I see the show"
end
Scenario "registered user gets the index" do
Given "logged in user"
And "an article"
When "I GET the page", article_path(@article)
Then "I see the show"
end
end
Surely it looks much more readable and still will be executed and do what you need. And there's another trick I haven't mentioned. This piece of code
define.then "I see the $page_name" do |page_name|
response.should render_template(page_name)
end
Inside the steps definition. This magic construction "$page_name" will parse out the template name right out of the passed step name and put it into the block. Therefore you can write your steps like
Then "I see the index"
.............................
Then "I see the show"
The same step will be involved, but first time with the 'index' page_name, and the second with the 'show' page_name.
This way you can define your own small macro-language to describe your system behavior with short and easy to understand phrases. You even might show the stuff to your customer and he will understand what's going on and will be sure that the system is doing what he need.
And this is not the end again. As you probably noticed, that after you have moved all the steps code into a standalone class, your story contains nothing but text. In such case you can even go further and put your stories in a plain text. In a such format
Story: articles browsing
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles
Scenario: anonymous user gets the index
Given an article
When I GET the page /articles
Then I see the index
Scenario: registered user gets the index
Given logged in user
And an article
When I GET the page /articles
Then I see the index
Isn't that great? You can save that text in a file and then execute it with a simple runner, similar to this one.
require 'rspec'
require 'your_gears' # <- require your necessary files
runner = Spec::Story::Runner::PlainTextStoryRunner.new('your/plain/text/story/file/name')
runner.steps << ArticlesAccessSteps.new
runner.run
You may have one script for all of your textual stories it's up to you. And you'll need to change a little your When step to be like
When "I GET the page $path"
so it was catching up your urls you specify in the story.That's it. If you ever written integration tests with the native rails integration tests framework, you probably noticed how ugly and complex they tend to become when the application logic gets serious. So the Story Framework of RSpec offers you an excellent opportunity to change the things for better. With stories you can easily organize your system behavior description in collections of simple scenarios and inside each scenario you can easily set up the necessary conditions, run necessary actions and check the result. And that more important you can do in a very simple way, just with few short strings which anyone can understand.
That's what I wanted to show today.
So long and write the stories it's fun! ;)
Wednesday, March 12, 2008
RSpec Dummyfication
When you're working with rspec and describing models relations you probably will need some dummy models, which wont bother you with all those validation stuffs. Yes, there's mock_model method, but the problem with it is that it stubs all the model methods first and the mocks don't have any relationships with the database.
And then if you need for your integration tests real models which will respond as real models and have database identification, you probably might find useful the following trick. Add the following strings into your spec_helper.rb file.
After this you'll be able to create dummy model instances in your specs like that
This way you will be able to create new and new database records which will behave just as they should except the validation, so you can concentrate on the models relations not worrying about the models validation.
And then if you need for your integration tests real models which will respond as real models and have database identification, you probably might find useful the following trick. Add the following strings into your spec_helper.rb file.
module Dummyficator
def dummy_inst(klass, attrs={ })
inst = klass.new attrs
inst.stub!(:valid?).and_return(true)
inst.save
inst
end
end
include Dummyficator
After this you'll be able to create dummy model instances in your specs like that
describe Group, "with users" do
before do
@group = dummy_inst Group
@group << dummy_inst User
@group << dummy_inst User, :username => 'dummy'
end
it "should have two users" do
@group.should have(2).users
end
it "should not destroy users" do
@group.destroy
User.find_by_username('dummy').should_not be_nil
end
end
This way you will be able to create new and new database records which will behave just as they should except the validation, so you can concentrate on the models relations not worrying about the models validation.
Monday, March 10, 2008
The arguments.callee trick
Inside a JavaScript function, you have an access to the local variable
But this variable is not a list in really, I mean it's not an instance of Array class and it does have additional attributes. For example
This attribute
Here you go, another brain-kicker with my faworite camelization task.
See? Generally you can do it only with a prototype method or with a named function. But if you feel particularly evil and wish it have with a lambda function, you can do it like that with
This is pretty much it.
arguments
, which simulates the list of all the arguments passed to the function. It's quite useful when you have got a function which might be called with different number of arguments.But this variable is not a list in really, I mean it's not an instance of Array class and it does have additional attributes. For example
.callee
and dispite it has been marked as depricated feature since JavaScript version 1.5 then it's still working and interesting stuff.This attribute
arguments.callee
refers to the current function by itself. It might look pointless, but in really it's quite handy. Say for example with lambda functions, like I showed once that tricks with (function(){...})();
constructions. Such functions don't have any variables which points on them, so if you need to have some lovely recursion in there, you will need this .callee stuff.Here you go, another brain-kicker with my faworite camelization task.
alert((function(str) {
var _pos = str.lastIndexOf('_'), suffix = str.substr(_pos+1);
return _pos < 1 ? str : arguments.callee.apply(null, [str.substr(0, _pos)])
+ suffix.charAt(0).toUpperCase() + suffix.substr(1);
})('asdf_asdf_asdf'));
See? Generally you can do it only with a prototype method or with a named function. But if you feel particularly evil and wish it have with a lambda function, you can do it like that with
arguments.calle
.This is pretty much it.
Sunday, March 2, 2008
TestCase 2.0-alpha is out
As I mentioned the TestCase project is going to be framework independent and now it is.
I've just released the version 2.0-alpha of the project. Functionally it's the same TestCase v 1.0, but the project had some major internal changes so now it runs on its own.
The project is designed such a way that it won't affect any framework stuffs, so you can safely use it with any of your projects. Use it with the lovely mootools or with jQuery if you wish so.
That's it, have fun.
I've just released the version 2.0-alpha of the project. Functionally it's the same TestCase v 1.0, but the project had some major internal changes so now it runs on its own.
The project is designed such a way that it won't affect any framework stuffs, so you can safely use it with any of your projects. Use it with the lovely mootools or with jQuery if you wish so.
That's it, have fun.
Friday, February 22, 2008
Testing, Refactoring, Patterns
I'm going to invent new abbreviation now. Testing, Refactoring, Patterns or TRP. The holly trinity of any good programmer and I'm going to talk about this things today, because many young programmers "those days" don't get the sake of the things right.
First things first. Testing.
I'm pretty much sure that you've heard this, but I'll repeat, that there's no excuse to not use tests. I know, many people think that it takes quite a big overhead and so it's boring, etc. I myself used to think like that, but believe me, once you start testing you won't stop. Think about it, do you know anyone who used to be a good TDD adept and then gave it up? I don't know any.
There's an edge which you should step over in order to become a good programmer and it's testing. The first time it will disturb you and you'll feel annoyed but then you will like it. Remember there are the things which you should get used to.
But keep in mind, many people do write tests, they madly covers each line of the code with tests, then write tests for tests and still produce a crap. And there's a reason, you should not concentrate on the tests themselves and make any kind of cult on it. Testing have it's own meaning and this is not an abstract safety, that's an ability to make your code better. Yes sir, you may write a good bunches of tests on your code and feel yourself safe but if you don't make your code better then, you was just wasting your time writing the tests.
Tests provides you an ability to improve your code safely. Once you have written some tests you may change your code, make some research, try this and that, find new tricks and do it safely. And once something went wrong you can easily see where and how it happened. Tests will teach you to write better code, and once you'll start to change your code you'll came to the second part of TRP.
Refactoring.
And this is the knowledge about how to change your code. Mr. Fowler had written an excellent book on this and invented a good system of "bad smells", the system which will point you at problematic parts in your code.
Yes, you may learn refactoring without tests, but then you will only suffer and won't ever open for yourself a truly power of the instrument. Refactoring needs practice, you should do it over and over until you instinctively will avoid problematic code pieces.
Once you will becoming better and better in refactoring you'll came to understanding of bigger parts of code and then you'll need the P of TRP.
Software Design Patterns.
It is said that patterns are for architects and team leaders only. But not in really. Patterns are trusted and many times rechecked software design solutions. They tell you how good people do it.
Once you started to practice refactoring you will need patterns, to not change your code blindly. Having patterns in your mind you'll do refactoring more consciously and more important you will try to make your code more standard, more understable for another readers and yourself first.
And yes again. You may start learn patterns separately of testing and refactoring but it won't give you much, case you won't be able to use it effectively without an experience in code refactoring.
Conclusion
TRP - Testing, Refactoring, Patterns. Those three things are wired tightly in reality and each one helps two another. You cannot be seriously good in any of those separately and should grow them up all together.
And do not be religious about the things, remember only the quantity separates venom out of cure. Teach yourself to feel the measure and you'll be gold.
First things first. Testing.
I'm pretty much sure that you've heard this, but I'll repeat, that there's no excuse to not use tests. I know, many people think that it takes quite a big overhead and so it's boring, etc. I myself used to think like that, but believe me, once you start testing you won't stop. Think about it, do you know anyone who used to be a good TDD adept and then gave it up? I don't know any.
There's an edge which you should step over in order to become a good programmer and it's testing. The first time it will disturb you and you'll feel annoyed but then you will like it. Remember there are the things which you should get used to.
But keep in mind, many people do write tests, they madly covers each line of the code with tests, then write tests for tests and still produce a crap. And there's a reason, you should not concentrate on the tests themselves and make any kind of cult on it. Testing have it's own meaning and this is not an abstract safety, that's an ability to make your code better. Yes sir, you may write a good bunches of tests on your code and feel yourself safe but if you don't make your code better then, you was just wasting your time writing the tests.
Tests provides you an ability to improve your code safely. Once you have written some tests you may change your code, make some research, try this and that, find new tricks and do it safely. And once something went wrong you can easily see where and how it happened. Tests will teach you to write better code, and once you'll start to change your code you'll came to the second part of TRP.
Refactoring.
And this is the knowledge about how to change your code. Mr. Fowler had written an excellent book on this and invented a good system of "bad smells", the system which will point you at problematic parts in your code.
Yes, you may learn refactoring without tests, but then you will only suffer and won't ever open for yourself a truly power of the instrument. Refactoring needs practice, you should do it over and over until you instinctively will avoid problematic code pieces.
Once you will becoming better and better in refactoring you'll came to understanding of bigger parts of code and then you'll need the P of TRP.
Software Design Patterns.
It is said that patterns are for architects and team leaders only. But not in really. Patterns are trusted and many times rechecked software design solutions. They tell you how good people do it.
Once you started to practice refactoring you will need patterns, to not change your code blindly. Having patterns in your mind you'll do refactoring more consciously and more important you will try to make your code more standard, more understable for another readers and yourself first.
And yes again. You may start learn patterns separately of testing and refactoring but it won't give you much, case you won't be able to use it effectively without an experience in code refactoring.
Conclusion
TRP - Testing, Refactoring, Patterns. Those three things are wired tightly in reality and each one helps two another. You cannot be seriously good in any of those separately and should grow them up all together.
And do not be religious about the things, remember only the quantity separates venom out of cure. Teach yourself to feel the measure and you'll be gold.
Tuesday, February 19, 2008
Firefox 3 tries
Have installed FF 3-beta (Gecko/2008021416 Firefox/3.0b3), what can I say? Looks promising, they have revised many gui stuffs, now it looks quite nicer. And yes, as they had been promising, now it works with Cairo and renders native gtk widgets. That's cool.
But unfortunately, just as it was with FF 0.9 -> 1.0, FF 1.0 -> 1.5, FF 1.5 -> 2.0, all my plugins screwed up. No firebug, not firefox-webdevelop, etc. 8(
By itself FF 3, looks quite stable, had no problems so far, no crashes etc.
That's it. Will waiting.
But unfortunately, just as it was with FF 0.9 -> 1.0, FF 1.0 -> 1.5, FF 1.5 -> 2.0, all my plugins screwed up. No firebug, not firefox-webdevelop, etc. 8(
By itself FF 3, looks quite stable, had no problems so far, no crashes etc.
That's it. Will waiting.
Monday, February 18, 2008
Charged php-mode recharge
PHP is like a gangsta-rap. Everyone know that it's a bullshit, but from time to time do it for living.
So, as I had to support one of my customers with an old php-project recently, I've done some fixes in the charged php-mode. There are only minor fixes of highlighting issues, like the broken methods calls highlighting, $this_ calls lack, etc.
Get It Here
So, as I had to support one of my customers with an old php-project recently, I've done some fixes in the charged php-mode. There are only minor fixes of highlighting issues, like the broken methods calls highlighting, $this_ calls lack, etc.
Get It Here
Thursday, February 14, 2008
discovery.com seems to have nice round hole in their security
I was trying to register on their forum and accidentally found myself logged in under another user.
How did I do so:
1) Hit the Login/Join button
2) Proceed to the registration form
3) Feel it as they wish to
4) Enter instead of the desired username a username of an existing user
5) Press submit.
That's it. I've received the confirmation email and found myself under the user which was registered several years ago and have some posts. I even managed to create a post and now having the discussion.
How did I do so:
1) Hit the Login/Join button
2) Proceed to the registration form
3) Feel it as they wish to
4) Enter instead of the desired username a username of an existing user
5) Press submit.
That's it. I've received the confirmation email and found myself under the user which was registered several years ago and have some posts. I even managed to create a post and now having the discussion.
Tuesday, February 12, 2008
Epiphany updates look well
Monday, February 11, 2008
Recursive Camelization
Felt myself not much well since wrote a non-recursive camelization example in the yesterday article. So, now I'm fixing the lack ;)
That's it.
String.prototype._camelize = function() {
var _pos = this.lastIndexOf('_'), suffix = this.substr(_pos+1);
return _pos < 1 ? this : this.substr(0, _pos)._camelize()
+ suffix.charAt(0).toUpperCase() + suffix.substr(1);
};
alert('_camelize_me_pleaze'._camelize());
That's it.
Sunday, February 10, 2008
Binded Callbacks with Prototype
This article is all about using of the functions binding in callbacks when you're coding with the Prototype JavaScript Library.
We all know, that Prototype have got the Ruby's Enumerable module port in JavaScript. The idea is pretty simple, you've got a method where you put your callback function and when an object iterates through its stuffs it calls the function. Like that
That's fine, but there's a problem. When you write code like that, each such callback function creates an own scope and when you try to write a code like below it won't work
it will say you that there's no double_item function, and that's right, case it won't look for the proc.double_item function, it will search for the double_item method in the scope of the function object which you've sent as the attribute into the .collect method. (Which in the case will be the window object).
For such cases in the Enumerable module of Prototype defined an ability to pass another, optional attribute which will represent the scope in which the callback function should be applied.
With such a change the code will work, and you'll get the [2,4,6] alert.
That's nice. But if say you're implementing your own function which accepts a callback, and you don't want to pass the scope attribute. Something like that.
How can you handle that? That's easy. Prototype defines an additional method .bind(scope_object) for the functions, which returns another function which has the same interface but will execute the original function in the correct scope. Say you may write it like this.
Looks prettier, but this is not all again. What if you need not just to bind an existing method, but to make some additional handling, like that
What if you want a dumn function, like you used to have it with blocks in Ruby? That's easy, and kinda beauty. You can do it with that trick.
That's simple and maybe strange looking but it's handy. You may bind your functions on fly, and this's a quite often case.
And if you look closer you'll see the idea is in calling construction like
This is probably a quite dummy example and I should make it recursive to feel myself like a true hacker, but it shows the idea. You may apply functions on fly just in the time of their creation. Browse the Prototype's source code and you'll find lots of such tricks in there.
We all know, that Prototype have got the Ruby's Enumerable module port in JavaScript. The idea is pretty simple, you've got a method where you put your callback function and when an object iterates through its stuffs it calls the function. Like that
var foo = function() {
var two = [1, 2, 3, 4].find(function(item) {
return item == 2;
})
};
That's fine, but there's a problem. When you write code like that, each such callback function creates an own scope and when you try to write a code like below it won't work
var proc = {
make_it_double: function(list) {
return list.collect(function(item) {
return this.double_item(item);
});
},
double_item: function(i) {
return i * 2;
}
};
alert(proc.make_it_double([1,2,3]));
it will say you that there's no double_item function, and that's right, case it won't look for the proc.double_item function, it will search for the double_item method in the scope of the function object which you've sent as the attribute into the .collect method. (Which in the case will be the window object).
For such cases in the Enumerable module of Prototype defined an ability to pass another, optional attribute which will represent the scope in which the callback function should be applied.
.................
return list.collect(function(item) {
return this.double_item(item);
}, this);
// ^
// +---- here it is
...................
With such a change the code will work, and you'll get the [2,4,6] alert.
That's nice. But if say you're implementing your own function which accepts a callback, and you don't want to pass the scope attribute. Something like that.
var my_proc = {
handle: function(elements, callback, something) {
.............................
for (var i=0; i < elements.length; i++) {
var something = callback(elements);
}
.............................
}
};
var my_starter = {
foo: function() {
my_proc.handle([1,2,3,4,5], function(item) {
return this.update(item);
},....);
},
update: function(item) {
return item * 2;
}
};
How can you handle that? That's easy. Prototype defines an additional method .bind(scope_object) for the functions, which returns another function which has the same interface but will execute the original function in the correct scope. Say you may write it like this.
................................
foo: function() {
my_proc.handle([1,2,3,4,5], this.update.bind(this),....);
},
................................
Looks prettier, but this is not all again. What if you need not just to bind an existing method, but to make some additional handling, like that
................................
foo: function() {
var something = 'foo';
my_proc.handle([1,2,3,4,5], function(item) {
return something == 'foo' ? this.update(item) : 'bla';
},....);
},
................................
What if you want a dumn function, like you used to have it with blocks in Ruby? That's easy, and kinda beauty. You can do it with that trick.
................................
foo: function() {
var something = 'foo';
my_proc.handle([1,2,3,4,5], (function(item) {
return something == 'foo' ? this.update(item) : 'bla';
}).bind(this),....);
// ^
// +------------ Here you go
},
................................
That's simple and maybe strange looking but it's handy. You may bind your functions on fly, and this's a quite often case.
And if you look closer you'll see the idea is in calling construction like
(function() {})
, and actually you may go further and use it more like in the functional programming style. Say like that.
var caMeL = (function(str) {
var parts = str.split('_'), camelized = parts.shift();
for (var i=0; i < parts.length; i++)
camelized += parts[i].charAt(0).toUpperCase + parts[i].substr(1);
return camelized;
})('ca_me_l');
This is probably a quite dummy example and I should make it recursive to feel myself like a true hacker, but it shows the idea. You may apply functions on fly just in the time of their creation. Browse the Prototype's source code and you'll find lots of such tricks in there.
So much Groovy in the air
As the GRails hit the version 1.0 last week, there are so much articles about Groovy began to appear, more and more.
And this is the only beginning, case there are so much java developers tired of java and I predict a big hype around those stuffs ;). I had some experience with Groovy and GRails several monthes ago, when GRails was at version 0.5 and 0.6, that's a quite complex feeling, and this is about them.
Groovy, byitself is a tiny little ray of light in the Java world. Seriously. I'm not a big Java guru, but in my opinion, Groovy is the best damn thing happened with Java. You probably won't have so much beauty and easy feeling like with Ruby and definitely you won't have this cool-hacker feeling like with Python, but anyway Groovy is a very, very good language. It's a bit strange experience at the beginning, you try use it like Ruby and actually mostly can't, then you usually use the Java native libraries and all the time falling back to the Java coding approach. But after some tries and fails, after some readings, you get the idea of Groovy and it becomes more or less handy.
There are some good ideas in Groovy, like the how do they define everything, the authors were definitely inspired by a functional programming practicies, and as result you may do your lovely FP-paradigm with Groovy very much, there are all those nice stuffs like functions and carrying and so one. But then you always can fallback to more usual OOP stuffs. And definitely you may allow yourself all those metaprogramming goods you always been missing in Java :)
But on the other hand, you'll be printing all the time [ instead of {. If in same Ruby, Python, JavaScript etc. You have a standard meaning of [] - for lists, {} - for hashes. Then in Groovy they have all in {}, lists and hashes. It's again more like lists and lists of pairs in functional programming. So what can I say? It's not much friendly for people with different experience, but let em have it.
GRails, as I mentioned, I tried it when it was at version 0.5 and 0.6, and later I've looked through the version 1.0-rc. That was a quite, quite raw stuff those time. The behaviour was not much stable, always had some stranges in it, and sure I was not such happy and productive live with the original Rails. I would say it's a rails for java-developers (in the bad meaning of the word).
Heck those guys even don't support their own java-world stuff maven. The domain model constructions, like it usually is in java-world, very abstract and keeps you as much far from database as it possible. (I don't know why, but most Java-developers afraid SQL just as a fire). You don't have normal REST-idelogy support, you do have a doubtfull rest-pluging, but grails by itself don't have anything in it like that. I don't like the project's configuration, include the routes configuration, it was made out of hands. The testing organisation is quite bad. The internalization layer is "as usual in Java",- read rubbish. Very poor (at last after Rails) builtin functionality. And the biggest sin is no documentation. Almost at all. There are couple of useless books about Grails of old versions and some miserable articles and that was all. Almost no correct API documentation, no tips, not triks. And one strange screencast how to install grials with a horrible german accent :)
The only thing I liked in GRails at the time was the tag-libs feature. This is almost the same feature which you have in JSP, but you can define the tag-libs in Groovy, similar to the Rails helpers. And that was implemented quite handy, with namespaces, with normal inner blocks handling, etc. That's what I would like to have in Rails instead of erb.
And this is the only beginning, case there are so much java developers tired of java and I predict a big hype around those stuffs ;). I had some experience with Groovy and GRails several monthes ago, when GRails was at version 0.5 and 0.6, that's a quite complex feeling, and this is about them.
Groovy, byitself is a tiny little ray of light in the Java world. Seriously. I'm not a big Java guru, but in my opinion, Groovy is the best damn thing happened with Java. You probably won't have so much beauty and easy feeling like with Ruby and definitely you won't have this cool-hacker feeling like with Python, but anyway Groovy is a very, very good language. It's a bit strange experience at the beginning, you try use it like Ruby and actually mostly can't, then you usually use the Java native libraries and all the time falling back to the Java coding approach. But after some tries and fails, after some readings, you get the idea of Groovy and it becomes more or less handy.
There are some good ideas in Groovy, like the how do they define everything, the authors were definitely inspired by a functional programming practicies, and as result you may do your lovely FP-paradigm with Groovy very much, there are all those nice stuffs like functions and carrying and so one. But then you always can fallback to more usual OOP stuffs. And definitely you may allow yourself all those metaprogramming goods you always been missing in Java :)
But on the other hand, you'll be printing all the time [ instead of {. If in same Ruby, Python, JavaScript etc. You have a standard meaning of [] - for lists, {} - for hashes. Then in Groovy they have all in {}, lists and hashes. It's again more like lists and lists of pairs in functional programming. So what can I say? It's not much friendly for people with different experience, but let em have it.
GRails, as I mentioned, I tried it when it was at version 0.5 and 0.6, and later I've looked through the version 1.0-rc. That was a quite, quite raw stuff those time. The behaviour was not much stable, always had some stranges in it, and sure I was not such happy and productive live with the original Rails. I would say it's a rails for java-developers (in the bad meaning of the word).
Heck those guys even don't support their own java-world stuff maven. The domain model constructions, like it usually is in java-world, very abstract and keeps you as much far from database as it possible. (I don't know why, but most Java-developers afraid SQL just as a fire). You don't have normal REST-idelogy support, you do have a doubtfull rest-pluging, but grails by itself don't have anything in it like that. I don't like the project's configuration, include the routes configuration, it was made out of hands. The testing organisation is quite bad. The internalization layer is "as usual in Java",- read rubbish. Very poor (at last after Rails) builtin functionality. And the biggest sin is no documentation. Almost at all. There are couple of useless books about Grails of old versions and some miserable articles and that was all. Almost no correct API documentation, no tips, not triks. And one strange screencast how to install grials with a horrible german accent :)
The only thing I liked in GRails at the time was the tag-libs feature. This is almost the same feature which you have in JSP, but you can define the tag-libs in Groovy, similar to the Rails helpers. And that was implemented quite handy, with namespaces, with normal inner blocks handling, etc. That's what I would like to have in Rails instead of erb.
Friday, February 8, 2008
TestCase is going to be a framework independent
Initially when I started TestCase I just needed some testing facility for my Prototype based code and I was not satisfied with the scriptaculous testing way. But now, it becomes obvious to me that the project is not uses Prototype much in really and I seems need to test some MooTools based code, and then some people are too excited about jQuery.
So, I've thought that it will good for us all to make the TestCase project framework independent and put all the frameworks related stuffs in plugins or something like that.
That's it. Watch out, TestCase 2.0 is on its way to every mind ;)
So, I've thought that it will good for us all to make the TestCase project framework independent and put all the frameworks related stuffs in plugins or something like that.
That's it. Watch out, TestCase 2.0 is on its way to every mind ;)
Thursday, February 7, 2008
Javish source code formatting for the php-mode
If you tried the php-mode on Emacs, you probably meet the situation that it follows the c-mode rules in the code formatting. And if then you're more OOP apologist you probably would prefer some more javish-looking source code. Good news is that you actually can get so. Emacs is a totally configurable thing.
Put the following code into your emacs config.
This will provide you a correct 4-spaces indentation for all of your constructions. If you prefer tabs instead of spaces, change
Put the following code into your emacs config.
(defun my-phpstuff ()
(c-set-style "awk")
(c-set-offset 'arglist-close 0)
(c-set-offset 'string 'c-lineup-dont-change)
(c-set-offset 'arglist-cont-nonempty '+)
(c-set-offset 'case-label '+)
(c-set-offset 'comment-intro 0)
(c-set-offset 'defun-close 0)
(c-set-offset 'cpp-macro 0)
(c-set-offset 'knr-argdecl 'c-lineup-dont-change)
(setq tab-width 4
c-basic-offset 4
c-hanging-semi&comma-criteria nil
indent-tabs-mode nil
c-cleanup-list '(scope-operator)
c-comment-only-line-offset '(0 . 0)
c-backslash-column 48
c-hanging-colons-alist nil
c-hanging-comment-starter-p nil
c-hanging-comment-ender-p nil
c-indent-comments-syntactically-p nil
c-tab-always-indent t
c-comment-continuation-stars "* "
c-label-minimum-indentation 1
defun-prompt-regexp nil
)
)
(add-hook 'php-mode-hook 'my-phpstuff)
This will provide you a correct 4-spaces indentation for all of your constructions. If you prefer tabs instead of spaces, change
indent-tabs-mode nil
to indent-tabs-mode t
and you'll have it.
Wednesday, February 6, 2008
Charged php-mode for Emacs and something more
Case the official maintainers of the php-mode seems to be busy people I public it here.
This is a charged php-mode for Emacs. I mean it's the freshest php-mode with some fixes/updates/improvements which I've written for myself and now I share with you.
It's based on the latest php-mode version 1.4.0-beta and contains all the original features and adds some new
1) Fixes in the code highlighting, especially in_the_underscored_functions
2) Added the php's built-in functions highlighting
3) Added the php-doc tags highlighting like @param @return, TODO, FIXME etc.
4) Added a hotkey and functionality to execute the current php-buffer with usual C-c C-c command
5) Added a hotkey and functionality to execute the current buffer with the phpunit util (C-c C-p C-u command)
6) Some another highlighting fixes/improvements
This is the screenshot (click to see the full version). Hope it's not too much beautiful to you ;)
Get it here
And as I mentioned there's more
There's another sweet stuff for php-editing which had to exists but somehow didn't. It's a php-electric mode. Similar to another -electric modes for emacs, it put some hot magic under your fingers and creates language constructions for you when you type.
Try, you will like it. It's simple but handy and have the following features
* autocompletion for the if/for/foreach etc blocks
* autocompletion for the classes/interfaces/functions
* autocompletion for paired symbols like [] () "" ''
You can get it here
Both files might be easily inserted into your system. Just put them where emacs can see them (say in ~/.emacs.d/) and insert into your emacs config couple of strings like that.
That's it have fun!
This is a charged php-mode for Emacs. I mean it's the freshest php-mode with some fixes/updates/improvements which I've written for myself and now I share with you.
It's based on the latest php-mode version 1.4.0-beta and contains all the original features and adds some new
1) Fixes in the code highlighting, especially in_the_underscored_functions
2) Added the php's built-in functions highlighting
3) Added the php-doc tags highlighting like @param @return, TODO, FIXME etc.
4) Added a hotkey and functionality to execute the current php-buffer with usual C-c C-c command
5) Added a hotkey and functionality to execute the current buffer with the phpunit util (C-c C-p C-u command)
6) Some another highlighting fixes/improvements
This is the screenshot (click to see the full version). Hope it's not too much beautiful to you ;)
Get it here
And as I mentioned there's more
There's another sweet stuff for php-editing which had to exists but somehow didn't. It's a php-electric mode. Similar to another -electric modes for emacs, it put some hot magic under your fingers and creates language constructions for you when you type.
Try, you will like it. It's simple but handy and have the following features
* autocompletion for the if/for/foreach etc blocks
* autocompletion for the classes/interfaces/functions
* autocompletion for paired symbols like [] () "" ''
You can get it here
Both files might be easily inserted into your system. Just put them where emacs can see them (say in ~/.emacs.d/) and insert into your emacs config couple of strings like that.
(require 'php-mode)
(require 'php-electric)
That's it have fun!
Tuesday, February 5, 2008
How to defragment your XFS partition
If one beautiful morning, you like me found yourself having performance problems with reading from your huge XFS partition, you probably will think about defragmentation for the partition (at last if you had former windows experience). And will be right, case XFS in difference of ReiserFS needs a defragmenation. So this is how you may do it.
First you'll need to install some packages.
On your ubuntu/debian/suse whatever if you use the apt-get utility, say this.
Under Gentoo, this
Then you'll need to check if your partition needs a defragmentation in really
Once you see a scary fragmentation factor, run the command for the optimization
That's it, now you may go have a drink, lift something heavy, play the guitar or pay an attention to your girlfriend. This whill take some time.
First you'll need to install some packages.
On your ubuntu/debian/suse whatever if you use the apt-get utility, say this.
# apt-get install xfsdump
Under Gentoo, this
# emerge xfsprogs xfsdump
Then you'll need to check if your partition needs a defragmentation in really
# xfs_db -r /dev/sda5
xfs_db> frag
actual 22222222, ideal 2342342, fragmentation factor 99.9%
xfs_db> quit
Once you see a scary fragmentation factor, run the command for the optimization
# xfs_fsr -v /dev/sda5
.......
That's it, now you may go have a drink, lift something heavy, play the guitar or pay an attention to your girlfriend. This whill take some time.
Sunday, February 3, 2008
Client-side MVC
I'm going to describe my view on the client-side development, today. Under client-side, instantly I mean a complex of html/css/javascript which represents the user's interface in the web applications.
In general there's nothing new, this's just a slightly different point of view on the stuffs, which I've worked out for myself and which helps me to implement more complex and controllable solutions.
What is MVC.
MVC is one of the most well known software-programming pattern, originally, as I know, described by GOF. This pattern describes a point of view on any programming application as on a system which contains three main parts Model, View and Controller. Which mean in general the application data, application look'n'feel, and application logic. And if you keep the parts separated and don't mix them, you're good boy(girl) and keeps the things safe.
If you had no idea what MVC is before reading the article, you'd better proceed to same wiki for more details before reading further.
Preface.
You can meet this pattern almost in any good server-side system. Say same Rails (and all the clones), Django, TurboGears. All the modern web-frameworks follow the MVC rules. They have got a domain model which tied to the database structure, controllers which handle the users requests, and html templates which in the case are the view.
But when the people come to the client-side development, they usualy screw everything up, and began to produce a holly merry mix of all they have. And if a system is complex enough they soon come to problems.
The idea.
Among that, the idea of MVC in client-side development is on a surface. That's simple:
Your html/xhtml markuping - is a model,
Your css layer - is a view and
Your javascript - is a controller.
Yes, that's imple, but interesting not that, interesting the inquests you may learn out of this point of view on the system. Instantly if you are following the MVC idea, you should keep the parts as much separated as it's possible. In our case that means the following.
1) The markuping rules
Keep your markuping as much simple and clean as possible. That means no style="" attributes. Use as much suitable tags as it possible. UI for lists, TABLE for real tables, DIV for page blocks, span for inline elements, H1.. for your titles, etc. Try to be as much closer to the original tags meaning as it's possible.
Look at your markuping like on a real data-model. Your nodes should tell for themselves. Try too keep it with a minimum of class and id attributes. Don't use <div class="title" if you may use <h2> tag, etc. Remember you may make it look just as you need later. And read that fucking html manual at last! 8) I bet you'll find many rarely used tags which may replace many of yours divs with classes.
Try to not think about how you'll paint it later. Just make it have a resonable structure and look without any stylesheets.
Try to insert as less images as it possible. Use the <img tag only if you need to input a real image, like a photo or a diagram. If you need an icon, or a background or a design element, make it with a <div tag.
The main idea of all those tries, is to make your markuping the way that you won't need to change a single tag on a further redesign. Even if you're not going to make any redesign, such approach may safe you lot of time when you'll write your css and javascript.
2) The CSS layer rules
Put in your css layer as much design related stuffs as it's possible. Look at your css as on a thing which represents the application view. Put all colors, background images, icons, hover effects etc, here. If you followed the rules from 1) and keep your tags deversified, you'll have lots of abilities to paint your application just as you need.
The main idea here is that css-layer may be simple overloaded by additional stylesheets. If you keep all your design stuffs separated and one day one of your customers will ask you for a special logo for him or for a lovely another icons bunch, you'll be easy to do so just adding the customer specified css file without touching any of the original files.
The images in stylesheets worth an a special word. You may meet many goods and bads about keeping images such as icons and logos in css. But my own experience says me that it's a good idea and for a simple reason. One day it may be jpeg, another png, then gif. Then the sizes of images may be different, etc. If you have the images described in the css-layer, you may change it from here, otherwise you'll have to change the markuping.
And one more point. Keep in your css layer view of different states of the things as well. You'll probably need to define some additiona classes to represent different states of page elements, do so. Do not leave the things on your javascript, this is a metter of view and should be described in css.
3) JavaScript rules
When you writting your javascript always keep in mind that this is your controller and you are implementing the logic. Try to not put in javascript any element style changes. If you call a .style attribute that usually means you behave wrong and mix the things. If you need to change an element view, use your classes system from the css layer, use the addClassName and removeClassName methods. If you don't have an appropriate class in your css layer, create it there. Even if it will contain only one string, in further it will allow you to keep the things clean and controllable. All styles are metter of the view part of the system, do not change them directly from javascript.
And stupid but important, choose good names for the ids and classes in your markuping the way they were talking for themselves in your javascript code and you could always easily understand what's going on.
A simple example
For example you're implementing a dynamic menu. Write a simple and plain structure, like this
--- html ---
Then describe your menu view in your css, include the hover effects and current menu element related states.
--- css ---
Then write some plain javascript which will handle the menu states by switching the classes.
--- javascript ---
This is a very dummy example, it won't probably impress you with the power of the principles, but it displays the idea. Having the stuffs separated you may change them independently. Say having a good css-classes system which covers all the view points, you may change your model structure, add new elements and you always have a pretty simple structure which easily understable. Having a good deversified and smart structured model, you may change your css and change make your view look like you need. Having a good API of css class-names you may concentrate on logic in your javascript not worring how it will look later.
So, that's it, hope you had some interesting reading.
In general there's nothing new, this's just a slightly different point of view on the stuffs, which I've worked out for myself and which helps me to implement more complex and controllable solutions.
What is MVC.
MVC is one of the most well known software-programming pattern, originally, as I know, described by GOF. This pattern describes a point of view on any programming application as on a system which contains three main parts Model, View and Controller. Which mean in general the application data, application look'n'feel, and application logic. And if you keep the parts separated and don't mix them, you're good boy(girl) and keeps the things safe.
If you had no idea what MVC is before reading the article, you'd better proceed to same wiki for more details before reading further.
Preface.
You can meet this pattern almost in any good server-side system. Say same Rails (and all the clones), Django, TurboGears. All the modern web-frameworks follow the MVC rules. They have got a domain model which tied to the database structure, controllers which handle the users requests, and html templates which in the case are the view.
But when the people come to the client-side development, they usualy screw everything up, and began to produce a holly merry mix of all they have. And if a system is complex enough they soon come to problems.
The idea.
Among that, the idea of MVC in client-side development is on a surface. That's simple:
Your html/xhtml markuping - is a model,
Your css layer - is a view and
Your javascript - is a controller.
Yes, that's imple, but interesting not that, interesting the inquests you may learn out of this point of view on the system. Instantly if you are following the MVC idea, you should keep the parts as much separated as it's possible. In our case that means the following.
1) The markuping rules
Keep your markuping as much simple and clean as possible. That means no style="" attributes. Use as much suitable tags as it possible. UI for lists, TABLE for real tables, DIV for page blocks, span for inline elements, H1.. for your titles, etc. Try to be as much closer to the original tags meaning as it's possible.
Look at your markuping like on a real data-model. Your nodes should tell for themselves. Try too keep it with a minimum of class and id attributes. Don't use <div class="title" if you may use <h2> tag, etc. Remember you may make it look just as you need later. And read that fucking html manual at last! 8) I bet you'll find many rarely used tags which may replace many of yours divs with classes.
Try to not think about how you'll paint it later. Just make it have a resonable structure and look without any stylesheets.
Try to insert as less images as it possible. Use the <img tag only if you need to input a real image, like a photo or a diagram. If you need an icon, or a background or a design element, make it with a <div tag.
The main idea of all those tries, is to make your markuping the way that you won't need to change a single tag on a further redesign. Even if you're not going to make any redesign, such approach may safe you lot of time when you'll write your css and javascript.
2) The CSS layer rules
Put in your css layer as much design related stuffs as it's possible. Look at your css as on a thing which represents the application view. Put all colors, background images, icons, hover effects etc, here. If you followed the rules from 1) and keep your tags deversified, you'll have lots of abilities to paint your application just as you need.
The main idea here is that css-layer may be simple overloaded by additional stylesheets. If you keep all your design stuffs separated and one day one of your customers will ask you for a special logo for him or for a lovely another icons bunch, you'll be easy to do so just adding the customer specified css file without touching any of the original files.
The images in stylesheets worth an a special word. You may meet many goods and bads about keeping images such as icons and logos in css. But my own experience says me that it's a good idea and for a simple reason. One day it may be jpeg, another png, then gif. Then the sizes of images may be different, etc. If you have the images described in the css-layer, you may change it from here, otherwise you'll have to change the markuping.
And one more point. Keep in your css layer view of different states of the things as well. You'll probably need to define some additiona classes to represent different states of page elements, do so. Do not leave the things on your javascript, this is a metter of view and should be described in css.
3) JavaScript rules
When you writting your javascript always keep in mind that this is your controller and you are implementing the logic. Try to not put in javascript any element style changes. If you call a .style attribute that usually means you behave wrong and mix the things. If you need to change an element view, use your classes system from the css layer, use the addClassName and removeClassName methods. If you don't have an appropriate class in your css layer, create it there. Even if it will contain only one string, in further it will allow you to keep the things clean and controllable. All styles are metter of the view part of the system, do not change them directly from javascript.
And stupid but important, choose good names for the ids and classes in your markuping the way they were talking for themselves in your javascript code and you could always easily understand what's going on.
A simple example
For example you're implementing a dynamic menu. Write a simple and plain structure, like this
--- html ---
<ul id="main-menu">
<li><a href="home">Home</a></li>
<li class="current">
<a href="http:work">Work</a>
<ul>
<li......
</ul>
</li>
<li>
<a href="hell">Hell</a>
<ul>
<li.......
</ul>
</li>
</ul>
Then describe your menu view in your css, include the hover effects and current menu element related states.
--- css ---
#main-menu {....}
#main-menu li {.....}
#main-menu li a {.....}
#main-menu li a:hover {.....}
#main-menu li ul { display: none; }
#main-menu li:hover ul { display: block; }
/* represents the menu state */
#main-menu li.current a {......}
#main-menu li.current a:hover {.....}
#main-menu li.current ul { display: inline; }
Then write some plain javascript which will handle the menu states by switching the classes.
--- javascript ---
var Menu = Class.create({
initialize: function(element) {
$(element).immidiateDescendants().each((function(li) {
li.observe('click', this.choose.bindAsEventListener(li));
}).bind(this));
},
choose: function(event, li) {
// removing the 'current' class from all the li elements
li.up('ul').immidiateDescendants().each(function(element) {
element.removeClassName('current');
});
// adding the 'current' class to the clicked element
li.addClassName('current');
}
});
var menu = new Menu('main-menu');
This is a very dummy example, it won't probably impress you with the power of the principles, but it displays the idea. Having the stuffs separated you may change them independently. Say having a good css-classes system which covers all the view points, you may change your model structure, add new elements and you always have a pretty simple structure which easily understable. Having a good deversified and smart structured model, you may change your css and change make your view look like you need. Having a good API of css class-names you may concentrate on logic in your javascript not worring how it will look later.
So, that's it, hope you had some interesting reading.
Thursday, January 31, 2008
Subscribe to:
Posts (Atom)