Monday, October 24, 2011

Creating functions inside loops in Javascript

This is an ongoing effort to make Javascript a more robust programming language. So when one uses JSLint it complains about a number of bad coding practices.

One of its very rare occurrence is the creating of functions inside a loop.
Experienced programmers get into the habit of writing code like this:

var i;
for(i = 0 ; i < someValue; i++) {
  // some operations

  $(".a").onclick = (function() {
    $(this).href = // some manipulated code.

} // end for

While this has become a standard way of operating in Javascript, this is a bad practice, because you are creating functions for every iteration of the loop. 
Since in Javascript, functions are also allocated memory and can be accessed with their name references anywhere in the code, that is after their point of declaration, this coding practice unnecessarily creates many instances (the word instance is also debatable in Javascript, as Object Oriented means differently in here) of the function.

In order to keep the existing functionality, the code can be re-factored to meet the standards in this way:

var doSomething = function(){
  $(".a").onclick = //some manipulated code.

var i;
for(i = 0 ; i < someValue ; i++) {
  // some operations

  $(".a").onclick = doSomething();

} // end for

The beauty of this style of coding is more evident when the function becomes complex and takes in values.

Finding more than one record easily in Rails (with Ruby)

In order to find records from the database matching certain criteria, one can use the Rails find(:all) construct, passing to it all the required conditions, in a manner like this :

objects = Model.find(:all, :conditions => { :field1 => "value1", :field2 => value2, ... })

But this becomes much of an overkill if you want to specify only 2/3 conditions.

Let's suppose, the model is called Users and 2 of its fields, user_name and user_email are to be used in the condition.

We could rather use a shorthand form:

objects = Users.find_by_user_name_and_user_email("ABCD","")

Note that the order of values passed is picked up to match the field names mentioned in the calling method.

This has the same result as the more conventional:

objects = Users.find(:all, :conditions => {:user_name => "ABCD", :user_email => ""})

For one thing it reduces the need to type all the braces and the => operator and can be used effectively to reduce the typing and make code more readable.

The short-hand can be extended with as many fields but is not suggested as then it makes code all the more difficult to read.

Guidelines to writing specs for ROR.

Specs for
1) Controllers

  a) In most cases it is safe and advisable to set-up the test environment for the specs to be run. So the following code becomes a habit at the beginning of each controller's spec

Note that the line numbers indicate the position of code relative to each other in the actual specs file.

1.   describe ExampleController, :type => :controller do
2.   before :each do
3.     request.env["HTTP_HOST"] = "test"
4.     User.delete_all
5.   end
6.   ...
7.   end

Though the part after the name of the controller on the first line is not absolutely necessary, adding it provides good heads-up to the reader of the code.

  b) To test any method of the controller, begin by describing it as the following lines in place of line 6 in the code.

6.  describe "#method_name" do
7.    # Tests
8.  end

c)  Then add some steps which you might require before the test begins by setting up pseudo-variables and values.

6.   describe "#method_name" do

7.    before do
8.      @user = Factory.create(:user)
9.      @objects = Factory.create(:object, :parameter_name => parameter_value, ...)
10.    # Tests
11.  end

In this step you should generate all objects needed by the spec to run properly. This is done so as to mimic to Rails that an actual object is being passed to the controller and it can use any of its properties that it may need in this methods. Hence, you have to pass all such values, which will be used for that object in the concerned method, at the point of creation of that variable.
    In this case it is @objects which can be based on any model and parameter_names would be the list of attributes of @object which will be used in the method_name method. You should pass them on to the controller with which it can complete the method execution, without which it will fail, as the object is a dummy one and would not have any value you don't explicitly assign. Having said that, it is not necessary to pass all the attributes. You need only pass those values which are of specific concern to the method being tested. For eg., 
    @user object will generally have a lot of test values assigned to it. If for any reason, you want the email-id, for example, to be of some specific domain for your method to complete, then we must pass its value as "" at the time of creation of @user.

d)  From this point on, it is time for getting in to the details of the method.
          So different methods have different nature, and they should be tested in their own ways.
          1)  Simple - Methods which are straight-forward in their behavior and proceed along a straight path of execution may fall into this category.
                       They only place calls to few other methods and at the end may/may not generate some specific kinds of pages.
                       You should add a "it" line which gives a sense to the reader of the code. Or a "context" line would also serve the same purpose.

6.    describe "#method_name" do
12.      (it/context) "should do this and that and return successfully" do
13.       controller.should_receive(:method1_name)
14.       controller.should_receive(:method2_name)

These are the names of the methods which will be called during the method_name's period. So we expect the controller to receive calls to them. If in the method you are calling method_other of any other model, say ModelA, then that should also be tested in here, by :- 

15.       ModelA.should_receive(:method_other)

If you are certain that a method will be called x number of times and want to verify that,

16.     controller/ModelA.should_receive(:method_other).exactly(x).times

2) Complex - These are the methods which create a number of objects in their period and also execute some statements which find specific objects from other models and tables. Then they use that to fire other complex operations and eventually fire validations on these objects received.
                    At this point you would have to create a number of fake objects by either stub-ing them or mock-ing them from their models.

@user = Factory.stub(:user) OR
@object_name = mock(ModelName, :parameter_name1 => 
parameter_value ...)

Note that the parameter_name1 has to be pre-pended with a : for Rails to identify properly an attribute of the ModelName being referred to but the parameter_value is mostly in the form of values, as in "value1" for string types or 123 for number types and so on.
                    These lines come mostly in the before do sections of the method or the before :each section of the controller, if the values being created are to be used throughout the controller code, which is a very rare case.
                    Once you have all the objects ready, comes the part where you have to stub method definitions, which is the most complex part.
                    We stub methods, meaning provide false definitions to the controller for those methods which you don't want the controller to run. You would do this because you don't write specs to monitor the entire method definition, but only to test specific portions of the method. So if there are some methods which might not run on the server/local because of some setup-limitations, so instead of letting the spec to fail, one should stub it out.
                    We do this, generally in the before do section, by:
8.  ModelName.stub(:additional_method_name).and_return(@variable)
                  Now the second part is extremely crucial if the method_name expects additional_method_name to return some values and use it in some future validations. If you simply stub the additional_method_name, any dependencies on it would cause the spec to fail. Hence if the additional_method_name returns an object of type ModelC, we generally apply the following procedure to stub it out safely

6.   before do
7.     @objectC = mock(ModelC, list_of_required_parameters...)    
8.     ModelName.stub!(:additional_method_name).and_return(@objectC)

Which tells Rails to assume that the additional_method_name returned the object @objectC and use it for future operations. 
               Once all of this is set-up, you are ready to place a call to the method_name. It can be done in one of the two ways:

17.    get :method_name, :parameter_name => parameter_value ...

which is the standard and most common way of calling the method with the set of values it expects.
                    But sometimes, there can be validations in the method_name to check if the request type had been post, only then continue, else return. In which case the previous statement becomes like:

17.    post :method_name, :parameter_name => parameter_value ...

Now that calling the method is done, it becomes essential to see the return from the method and test it against various conditions, which may be among the following:

18.  response.response_code.should == 200  (Checks for a successful return)
response.should  render_template('template_name')    (Checks that after the method, the expected template is being rendered)
response.should redirect_to(:controller => 'controller_name', :action => 'action_name', ...)

(this line checks that the page should be redirected to the action_name method of the controller_name controller and with a set of parameters. This line is mostly a copy of the statement in the controller method, wherein we verify if the expected thing actually happened.)
It might also be possible that the method_name creates objects of certain types, say ModelX, and you need to check if it really got created.

18.   object_variable = ModelX.find(:all, :conditions => { list of condition hash})

this line tries to find the object being created by passing a known set of conditions. Since the method must have created such an object, we verify it by:

19.   object_variable.should_not == nil

But to be 100% sure that this object had not been existing in the DB before this method spawned, you have to delete the table in the before do section of the method. Be rest assured it does not harm the data as all of this creation and deletion is only done in the test environment.

7.    ModelX.delete_all 

2) Models

    1.  describe ModelClassName, :type => :model do
    To note is, that the ModelClassName must be the same as the model name for which the spec is being written.
    In models the only difference comes in the way of calling the method in line 17.
    line 17 becomes
    17.   ModelName.method_name(list of parameters)
3) Helpers

  If you need to stub the helper with some values,

  1.  describe  HelperClassName, :type => :helper do
  To note is, that the HelperClassName must be the same as the name of the helper for which the spec is being written.

  helper.stub!(:param_name).and_return({list of values in hash style})
  In order to call the method, you would
  helper.method_name.should == #something.
  and the method expectancy tests go on.

XOR trivialities

XOR trivialities

Shortcuts for XOR and XNOR

The classical formula for XOR on two variables remains

result = a.b' + b.a'

(where . means logical AND and + means logical OR and ' means logical NOT).

On the possible set of values, the table becomes something like :

a b result
0 0 0
0 1 1
1 0 1
1 1 0

which boils down to the interpretation of ANY BUT NOT ALL. This holds true for any no of variables in question, i.e.,
a ^ b ^ c ^ d ^ e ^ ....... x ^ y ^ z = 0
(iff all a, b, c ... z == 0|1 together. And ^ denotes XOR operation.)

So when it comes to applying an XOR formula to 2 variables, say a & b and storing their result in a variable, say x.

The starting point would be
x = (a AND !b) OR (b AND !a).

While this is correct, problems may arise when a & b are themselves functions which return true/false. In this case, the functions a & b would be executed twice just to compute the value of x. In cases where this may not be desired, we could stick to the short hand equivalent for XOR.

x = (a != b)

Which says that the result will be 1(true) only when both the variables are not the same, as can be inferred from the truth table above.

It solves many problems:
  • Reduces typing effort
  • Doesn't evaluate functions twice
  • Reduces complexity when a & b themselves become large expressions.
  • Makes code easy to read and understand and maintain
Similar interpretation could be extended to the function XNOR, which in its formula looks like:

result = (a XOR b)', where ' means logical complement.

  result = (a.b' + b.a')'
         = (a'+b) . (b'+a)
         = a'b' + b.b' + b.a + a'.a
         = a.b + a'.b'

In plain words, we could simply derive that
  a XNOR b  = !(a XOR b)
            = !(a != b)
a XNOR b = (a == b)

But for the curious reader, the truth table should be enough proof:

Taking the derived formula
result = a.b + a'.b'

a b result
0 0 1
0 1 0
1 0 0
1 1 1

Readers to this point can observe that the result is 1(true) only when (a == b).