With the usage of alias the method “name” is not able to pick the method “full_name” defined in Developer.
This is because alias is a keyword and it is lexically scoped. It means it treats self as the value of self at the time the source code was read . In contrast alias_method treats self as the value determined not at the run time.
Overall my recommendation would be to use alias_method. Since alias_method is a method defined in class Module it can be overridden later and it offers more flexibility. Also because of lexical scoping of alias it can do some weird things unless all the developers who whats going on.
Backbone.js users use bind and bindAll methods provide by underscore.js a lot. In this blog I am going to discuss why these methods are needed and how it all works.
It all starts with apply
Function bindAll internally uses bind . And bind internally uses apply. So it is important to understand what apply does.
1234
varfunc=functionbeautiful(){alert(this+' is beautiful');};func();
If I execute above code then I get [object window] is beautiful. I am getting that message because when function is invoked then this is window, the default global object.
In order to change the value of this we can make use of method apply as given below.
1234
varfunc=functionbeautiful(){alert(this+' is beautiful');};func.apply('Internet');
In the above case the alert message will be Internet is beautiful . Similarly following code will produce Beach is beautiful .
1234
varfunc=functionbeautiful(){alert(this+' is beautiful');};func.apply('Beach');//Beach is beautiful
In short, apply lets us control the value of this when the function is invoked.
Why bind is needed
In order to understand why bind method is needed first let’s look at following example.
Above example is pretty straight forward. john is an instance of Developer and when says function is invoked then we get the right alert message.
Notice that when we invoked says we invoked like this john.says(). If we just want to get hold of the function that is returned by says then we need to do john.says. So the above code could be broken down to following code.
Above code is similar to the code above it. All we have done is to store the function in a variable called func. If we invoke this function then we should get the alert message we expected. However if we run this code then the alert message will be undefined rocks!.
We are getting undefined rocks! because in this case func is being invoked in the global context. this is pointing to global object called window when the function is executed. And window does not have any attribute called skill . Hence the output of this.skill is undefined.
Earlier we saw that using apply we can fix the problem arising out of this. So lets try to use apply to fix it.
Above code fixes our problem. This time the alert message we got was Ruby rocks!. However there is an issue and it is a big one.
In JavaScript world functions are first class citizens. The reason why we create function is so that we can easily pass it around. In the above case we created a function called func. However along with the function func now we need to keep passing john around. That is not a good thing. Secondly the responsibility of rightly invoking this function has been shifted from the function creator to the function consumer. That’s not a good API.
We should try to create functions which can easily be called by the consumers of the function. This is where bind comes in
To solve the problem regarding this issue we need a function that is already mapped to john so that we do not need to keep carrying john around. That’s precisly what bind does. It returns a new function and this new function has this bound to the value that we provide.
Above code is similar to bind solution but there are some big differences.
The first big difference is that we do not have to worry about the returned value of bindAll . In case of bind we must use the returned function. In bindAll we do not have to worry about the returned value but it comes with a price. bindAll actually mutates the function. What does that mean.
See john object has an attribute called says which returns a function . bindAll goes and changes the attribute says so that when it returns a function, that function is already bound to john.
Herer is a snippet of code from bindAll method.
1
function(f){obj[f]=_.bind(obj[f],obj);}
Notice that bindAll internally calls bind and it overrides the existing attribute with the function returned by bind.
The other difference between bind and bindAll is that in bind first paramter is a function john.says and the second parameter is the value of this john. In bindAll first paramter is value of this john and the second parameter is not a function but the attribute name.
Things to watch out for
While developing a Backbone.js application someone had code like this
C programming language allows developers to directly access the memory where variables are stored. Ruby does not allow that. There are times while working in Ruby when you need to access the underlying bits and bytes. Ruby provides two methods pack and unpack for that.
Here is an example.
12
$'A'.unpack('b*')=>["10000010"]
In the above case ‘A’ is a string which is being stored and using unpack I am trying to read the bit value. The ASCII table says that ASCII valule of ‘A’ is 65 and the binary representation of 65 is 10000010 .
Here is another example.
12
$'A'.unpack('B*')=>["01000001"]
Notice the difference in result from the first case. What’s the difference between b and B. In order to understand the difference first lets discuss MSB and LSB.
Most significant bit vs Least significant bit
All bits are not created equal. C has ascii value of 67. The binary value of 67 is 1000011.
First let’s discuss MSB (most significant bit) style . If you are following MSB style then going from left to right (and you always go from left to right) then the most significant bit will come first. Because the most significant bit comes first we can pad an additional zero to the left to make the number of bits eight. After adding an additional zero to the left the binary value looks like 01000011.
If we want to convert this value in the LSB (Least Significant Bit) style then we need to store the least significant bit first going from left to right. Given below is how the bits will be moved if we are converting from MSB to LSB. Note that in the below case position 1 is being referred to the leftmost bit.
move value 1 from position 8 of MSB to position 1 of LSB
move value 1 from position 7 of MSB to position 2 of LSB
move value 0 from position 6 of MSB to position 3 of LSB
and so on and so forth
After the exercise is over the value will look like 11000010.
We did this exercise manually to understand the difference between most significant bit and least significant bit. However unpack method can directly give the result in both MSB and LSB. The unpack method can take both b and B as the input. As per the ruby documentation here is the differnce.
B | bit string (MSB first)
b | bit string (LSB first)
H | hex string (high nibble first)
h | hex string (low nibble first)
A byte consists of 8 bits. A nibble consists of 4 bits. So a byte has two nibbles. The ascii value of ‘h’ is 104. Hex value of 104 is 68. This 68 is stored in two nibbles. First nibble, meaning 4 bits, contain the value 6 and the second nibble contains the value 8. In general we deal with high nibble first and going from left to right we pick the value 6 and then 8.
However if you are dealing with low nibble first then low nibble value 8 will take the first slot and then 6 will come. Hence the result in “low nibble first” mode will be 86.
This pattern is repeated for each byte. And because of that a hex value of 68 65 6c 6c 6f looks like 86 56 c6 c6 f6 in low nibble first format.
Mix and match directives
In all the previous examples I used . And a means to keep going as long as it has to keep going. Lets see a few examples.
Rather than repeating all those directives, I can put a number to denote how many times you want previous directive to be repeated.
12
$"hello".unpack('C5')=>[104,101,108,108,111]
I can use * to capture al the remaining bytes.
12
$"hello".unpack('C*')=>[104,101,108,108,111]
Below is an example where MSB and LSB are being mixed.
12
$"aa".unpack('b8B8')=>["10000110","01100001"]
pack is reverse of unpack
Method pack is used to read the stored data. Let’s discuss a few examples.
12
$[1000001].pack('C')=>"A"
In the above case the binary value is being interpreted as 8 bit unsigned integer and the result is ‘A’.
12
$['A'].pack('H')=>"\xA0"
In the above case the input ‘A’ is not ASCII ‘A’ but the hex ‘A’. Why is it hex ‘A’. It is hex ‘A’ because the directive ‘H’ is telling pack to treat input value as hex value. Since ‘H’ is high nibble first and since the input has only one nibble then that means the second nibble is zero. So the input changes from [‘A’] to [‘A0’] .
Since hex value A0 does not translate into anything in the ASCII table the final output is left as it and hence the result is \xA0. The leading \x indicates that the value is hex value.
Notice the in hex notation A is same as a. So in the above example I can replace A with a and the result should not change. Let’s try that.
12
$['a'].pack('H')=>"\xA0"
Let’s discuss another example.
12
$['a'].pack('h')=>"\n"
In the above example notice the change. I changed directive from H to h. Since h means low nibble first and since the input has only one nibble the value of low nibble becomes zero and the input value is treated as high nibble value. That means value changes from [‘a’] to [‘0a’]. And the output will be \x0A. If you look at ASCII table then hex value A is ASCII value 10 which is NL line feed, new line. Hence we see \n as the output because it represents “new line feed”.
Usage of unpack in Rails source code
I did a quick grep in Rails source code and found following usage of unpack.
Already we have seen the usage of directive C and H for unpack. The directive m gives the base64 encoded value and the directive U gives the UTF-8 character. Here is an example.
I you already know how this infinite hash works then you are all set. If not read along.
Default value of Hash
If I want a hash to have a default value then that’s easy.
12
h=Hash.new(0)putsh['usa']#=> 0
Above code will give me a fixed value if key is not found. If I want dynamic value then I can use block form.
123
h=Hash.new{|h,k|h[k]=k.upcase}putsh['usa']#=> USAputsh['india']#=> INDIA
Default value is hash
If I want the default value to be a hash then it seems easy but it falls apart soon.
1234
h=Hash.new{|h,k|h[k]={}}putsh['usa'].inspect#=> {}putsh['usa']['ny'].inspect#=> nilputsh['usa']['ny']['nyc'].inspect#=> NoMethodError: undefined method `[]' for nil:NilClass
In the above if a key is missing for h then it returns a hash. However that returned hash is an ordinary hash which does not have a capability of returning another hash if a key is missing.
This is where default_proc comes into picture. hash.default_proc returns the block which was passed to Hash.new .
If you want output in xml format then request with .xml extension at the end like this localhost:3000/users.xml and you will get the outupt in xml format.
What we saw is only one part of the puzzle. The other side of the equation is HTTP header field Accept defined in HTTP RFC.
HTTP Header Field Accept
When browser sends a request then it also sends the information about what kind of resources the browser is capable of handling. Here are some of the examples of the Accept header a browser can send.
If you are reading this blog on a browser then you can find out what kind of Accept header your browser is sending by visiting this link. Here is list of Accept header sent by different browsers on my machine.
Safari is saying that I can handle documents which are xml (application/xml), html (text/html) or plain text (text/plain) documents. And I can handle images such as image/png. If all else fails then send me whatever you can and I will try to render that document to the best of my ability.
Notice that there are also q values. That signifies the priority order. This is what HTTP spec has to say about q.
Each media-range MAY be followed by one or more accept-params, beginning with the “q” parameter for indicating a relative quality factor. The first “q” parameter (if any) separates the media-range parameter(s) from the accept-params. Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range, using the qvalue scale from 0 to 1 (section 3.9). The default value is q=1.
The spec is saying is that each document type has a default value of q as 1. When q value is specified then take that value into account. For all documents that have same q value give high priority to the one that came first in the list. Based on that this should be the order in which documents should be sent to safari browser.
application/xml (q is 1)
application/xhtml+xml (q is 1)
image/png (q is 1)
text/html (q is 0.9)
text/plain (q is 0.8)
\*/\* (q is 0.5)
Notice that Safari is nice enough to put a lower priority for */*. Chrome and Firefox also puts */* at a lower priority which is a good thing. Not so with IE which does not declare any q value for */* .
Look at the order again and you can see that application/xml has higher priority over text/html. What it means is that safari is telling Rails that I would prefer application/xml over text/html. Send me text/html only if you cannot send application/xml.
And let’s say that you have developed a RESTful app which is capable of sending output in both html and xml formats.
Rails being a good HTTP citizen should follow the HTTP_ACCEPT protocol and should send an xml document in this case. Again all you did was visit a website and safari is telling rails that send me xml document over html document. Clearly HTTP_ACCEPT values being sent by Safari is broken.
HTTP_ACCEPT is broken
HTTP_ACCEPT attribute concept is neat. It defines the order and the priority. However the implementation is broken by all the browser vendors. Given the case that browsers do not send proper HTTP_ACCEPT what can rails do. One solution is to ignore it completely. If you want xml output then request http://localhost:3000/users.xml . Solely relying on formats make life easy and less buggy. This is what Rails did for a long time.
Starting this commit ,by default, rails did ignore HTTP_ACCEPT attribute. Same is true for Twitter API where HTTP_ACCEPT attribute is ignored and twitter solely relies on format to find out what kind of document should be returned.
Unfortunately this solution has its own sets of problems. Web has been there for a long time and there are a lot of applications who expect the response type to be RSS feed if they are sending application/rss+xml in their HTTP_ACCEPT attribute. It is not nice to take a hard stand and ask all of them to request with extension .rss .
Parsing HTTP_ACCEPT attribute
Parsing and obeying HTTP_ACCEPT attribute is filled with many edge cases. First let’s look at the code that decides what to parse and how to handle the data.
Notice that if a format is passed like http://localhost:3000/users.xml or http://localhost:3000/users.js then Rails does not even parse the HTTP_ACCEPT values. Also note that if browser is sending */* along with other values then Rails totally bails out and just returns Mime::HTML unless the request is ajax request.
Next I am going to discuss some of the cases in greater detail which should bring more clarity around this issue.
Case 1: HTTP_ACCEPT is */*
I have following code.
1234
respond_todo|format|format.html{render:text=>'this is html'}format.js{render:text=>'this is js'}end
I am assuming that HTTP_ACCEPT value is */* . In this case browser is saying that send me whatever you got. Since browser is not dictating the order in which documents should be sent Rails will look at the order in which Mime types are declared in respond_to block and will pick the first one. Here is the corresponding code
What it’s saying is that if Mime::ALL is sent then pick the first one declared in the respond_to block. So be careful with order in which formats are declared inside the respond_to block.
The order in which formats are declared can be real issue. Checkout these twocases where the author ran into issue because of the order in which formats are declared.
So far so good. However what if there is no respond_to block. If I don’t have respond_to block and if I have index.html.erb, index.js.erb and index.xml.builder files in my view directory then which one will be picked up. In this case Rails will go over all the registered formats in the order in which they are delcared and will try to find a match . So in this case it matters in what order Mime types are registered. Here is the code that registers Mime types.
As you can see text/html is first in the list, text/javascript next and then application/xml. So Rails will look for view file in the following order: index.html.erb , index.js.erb and index.xml.builder .
Case 2: HTTP_ACCEPT with no */*
I am going to assume that in this case HTTP_ACCEPT sent by browser looks really simple like this
text/javascript, text/html, text/plain
I am also assuming that my respond_to block looks like this
1234
respond_todo|format|format.html{render:text=>'this is html'}format.js{render:text=>'this is js'}end
So browser is saying that I prefer documents in following order
js
html
plain
The order in which formats are delcared is
html (format.html)
js (format.js)
In this case rails will go through each Mime type that browser supports from top to bottom one by one. If a match is found then response is sent otherwise rails tries find match for next Mime type. First in the list of Mime types suppported by browser is js and Rails does find that my respond_to block supports .js . Rails executes format.js block and response is sent to browser.
Case 3: Ajax requests
When an AJAX request is made the Safari, Firefox and Chrome send only one item in HTTP_ACCEPT and that is */*. So if you are making an AJAX request then HTTP_ACCEPT for these three browsers will look like
Chrome: */*
Firefox: */*
Safari: */*
and if your respond_to block looks like this
1234
respond_todo|format|format.html{render:text=>'this is html'}format.js{render:text=>'this is js'}end
then the first one will be served based on the formats order. And in this case html respsone would be sent for an AJAX request. This is not what you want.
This is the reason why if you are using jQuery and if you are sending AJAX request then you should add something like this in your application.js file
I was discussing JavaScript code with a friend and he noticed that I had declared all the variables at the top.
He likes to declare the variable where they are used to be sure that the variable being used is declared with var otherwise that variable will become global variable. This fear of accidentally creating a global variables wants him to see variable declaration next to where it is being used.
Use the right tool
12
varpayment;payment=soldPrice+shippingCost;
In the above case user has declared payment variable in the middle so that he is sure that payment is declared. However if there is a typo as given below then he has accidentally created a global variable “payment”.
12
varpaymnet;//there is a typopayment=soldPrice+shippingCost;
Having variable declaration next to where variable is being used is not a safe way of guarnateeing that variable is declared. Use the right tool and that would be jslint validation. I use MacVim and I use Javascript Lint. So every time I save a JavaScript file validation is done and I get warning if I am accidentally creating a global variable.
You can configure such that JSLint validation runs when you check your code into git or when you push to github. Or you can have a custom rake task. Many solutions are available choose the one that fits you. But do not rely on manual inspection.
Variable declaration are being moved to the top by the browser
Take a look at following code. One might expect that console.log will print “Neeraj” but the output will be “undefined” . That is because even though you have declaration variables next to where they are being used, browsers lift those declarations to the very top.
Looking at the first set of code a person might think that
Also remember that scope of variable in JavaScript at the function level.
Implications on how functions are declared
There are two ways of declaring a function.
12
varmyfunc=function(){};functionmyfunc2(){};
In the first case only the variable declaration myfunc is getting hoisted up. The defintion of myfunc is NOT getting hoisted. In the second case both variable declaration and function defintion is getting hoisted up. For more information on this refer to my previous blog on the same topic.
jQuery 1.4.3 was recently released. If you upgrade to jQuery 1.4.3 you will notice that the behavior of return false has changed in this version. First let’s see what return false does.
First ensure that above code is executed on domready. Now if I click on any link then two things will happen.
e.preventDefault() will be called .
e.stopPropagation() will be called .
e.preventDefault()
As the name suggets, calling e.preventDefault() will make sure that the default beahvior is not executed.
<a href='www.google.com'>click me</a>
If above link is clicked then the default behavior of the browser is to take you to www.google.com. However by invoking e.preventDefault() browser will not go ahead with default behavior and I will not be taken to www.google.com.
e.stopPropagation
When a link is clicked then an event “click event” is created. And this event bubbles all the way up to the top. By invoking e.stopPropagation I am asking browser to not to propagate the event. In other words the event will stop bubbling.
If I click on “click me” then “click event” will start bubbling. Now let’s say that I catch this event at .two and if I call e.stopPropagation() then this event will never reach to .first .
e.stopImmediatePropagation
First note that you can bind more than one event to an element. Take a look at following case.
<a class='one'>one</a>
I am going to bind three events to the above element.
In this case there are three events bound to the same element. Notice that second event binding invokes e.stopImmediatePropagation() . Calling e.stopImmediatePropagation does two things.
Just like stopPropagation it will stop the bubbling of the event. So any parent of this element will not get this event.
However stopImmdiatePropagation stops the event bubbling even to the siblings. It kills the event right then and there. That’s it. End of the event.
Once again calling stopPropagation means stop this event going to parent. And calling stopImmediatePropagation means stop passing this even to other evevent handlers bound to itself.
Since I am invoking e.stopImmediatePropagation I should never see alert world. However you will see that alert if you are using jQuery 1.4.3. You can play with it here .
This bug has been fixed as per this commit . Note that the commit mentioned was done after the release of jQuery 1.4.3. To get the fix you will have to wait for jQuery 1.4.4 release or use jQuery edge.
I am using rails.js (jquery-ujs). What do I do?
As I have shown “return false” does not work in jQuery 1.4.3 . However I would have to like have as much backward compatibility in jquery-ujs as much possible so that the same code base works with jQuery 1.4 through 1.4.3 since not every one upgrades immediately.
This commit should make jquery-ujs jquery 1.4.3 compatible. Many issues have been logged at jquery-ujs and I will take a look at all of them one by one. Pleaes do provide your feedback.
Nothing great there. However try passing a paramter to instance_eval .
1
putsKlass.new.instance_eval(self){@secret}
You will get following error.
1
wrongnumberofarguments(1for0)
So instance_eval does not allow you to pass parameters to a block.
How to get around to the restriction that instance_eval does not accept parameters
instance_exec was added to ruby 1.9 and it allows you to pass parameters to a proc. This feature has been backported to ruby 1.8.7 so we don’t really need ruby 1.9 to test this feature. Try this.
Above code works. So now we can pass parameters to block. Good.
Changing value of self
Another feature of instance_exec is that it changes the value of self. To illustrate that I need to give a longer example.
1234567891011121314151617181920212223
moduleKerneldefsingleton_classclass<<selfselfendendendclassHumanproc=lambda{puts'proc says my class is '+self.name.to_s}singleton_class.instance_evaldodefine_method(:lab)doproc.callendendendclassDeveloper<HumanendHuman.lab# class is HumanDeveloper.lab# class is Human ; oops
Notice that in that above case Developer.lab says “Human”. And that is the right answer from ruby perspective. However that is not what I intended. ruby stores the binding of the proc in the context it was created and hence it rightly reports that self is “Human” even though it is being called by Developer.
Evaluate the block with the given arguments within the context of this object, so self is set to the method receiver.
It means that instance_exec evaluates self in a new context. Now try the same code with instance_exec .
1234567891011121314151617181920212223
moduleKerneldefsingleton_classclass<<selfselfendendendclassHumanproc=lambda{puts'proc says my class is '+self.name.to_s}singleton_class.instance_evaldodefine_method(:lab)doself.instance_exec&procendendendclassDeveloper<HumanendHuman.lab# class is HumanDeveloper.lab# class is Developer
In this case Developer.lab says Developer and not Human.
You can also checkout this page which has much more detailed explanation of instance_exec and also emphasizes that instance_exec does pass a new value of self .
instance_exec is so useful that ActiveSupport needs it. And since ruby 1.8.6 does not have it ActiveSupport has code to support it.
I came across instance_exec issue while resolving #4507 rails ticket . The final solution did not need instance_exec but I learned a bit about it.
Rails developers know that in development mode classes are loaded on demand. In production mode all the classes are loaded as part of bootstrapping the system. Also in development mode classes are reloaded every single time page is refreshed.
In order to reload the class, Rails first has to unload . That unloading is done something like this.
12
# unload User classObjet.send(:remove_const,:User)
However a class might have other constants and they need to be unloaded too. Before you unload those constants you need to know all the constants that are defined in the class that is being loaded. Long story short rails keep track of every single constant that is loaded when it loads User or UserController.
Dependecy mechanism is not perfect
Sometimes dependecy mechanism by rails lets a few things fall through the crack. Try following case.
Start the server in development mode and visit http://localhost:3000/users . First time every thing will come up fine. Now refresh the page. This time you should get an exception uninitialized constant OpenURI .
So what’s going on.
After the page is served the very first time then at the end of response rails will unload all the constants that were autoloaded including UsersController. However while unloading UsersContorller rails will also unload OpenURI.
When the page is refreshed then UsersController will be loaded and require ‘open-uri’ will be called. However that require will return false.
irb(main):006:0>Object.send(:remove_const,:OpenStruct)NameError:constantObject::OpenStructnotdefinedfrom(irb):6:in`remove_const' from (irb):6:in `send'from(irb):6
Notice that in the above case in step 4 require returns false. ‘require’ checks against $LOADED_FEATURES. When OpenStruct was removed then it was not removed from $LOADED_FEATURES and hence ruby thought ostruct is already loaded.
How to get around to this issue.
require loads only once. However load loads every single time. In stead of ‘require’, ‘load’ could be used in this case.
In our rails application refresh of the page is failing. To get around to that issue use require_dependency instead of require. require_dependency is a rails thing. Under the hood rails does the same trick we did in the previous step. Rails calls kernel.load to load the constants that would fail if require were used.