Reputation: 13
I'm attempting to port the following JavaScript code to ruby: https://github.com/iguigova/snippets_js/blob/master/pokerIn4Hours/pokerIn4Hours.js
I think I have most of it sorted, the function that is giving me grief is:
var kickers = function(idx){ // http://en.wikipedia.org/wiki/Kicker_(poker)
idx = idx || -15;
var notplayed = Math.max(input.length - 1/*player input*/ - 5, 0);
return function(all, cardinality, rank) {
return (all || 0) + (((cardinality == 1) && (notplayed-- <= 0)) ? rank * Math.pow(10, ++idx) : 0);
};
}();
And it is called further down like so:
k = kickers(k, cardsofrank[i], i);
I was wondering if someone could explain how this works in JavaScript. The fact that the inner function has 3 parameters and the outer only has 1 is confusing, especially given that it is called with 3 parameters. I would like to understand what it's trying to accomplish, so that I can port the code with confidence.
Upvotes: 0
Views: 44
Reputation: 1517
var kickers = function(idx){
var xyz;//below function in return statement can access this and argument idx
return function(...) {//this ensures that your kickers is infact a function
};
}();//invoke this function instantly due to () and assign the output to kickers
When Javascript interpreter read above assignment to Kickers
it will execute the anonymous function
Since that function itself returns a function, the kickers
will now a function (with closure).
Meaning the kickers function will have a reference to the environment variables (idx and notplayed )
Edit:
1) Where it is getting value of idx - Since nothing is passed while invoking the function(last line ();
) the idx will be undefined and idx = idx || -15;
will assign the value -15 to it.
2) Could this be re-written without an inner function? - Yes. But the current implementation has an advantage where the scope of idx
and notplayed
is limited to kicker function and will not be accessible globally. Here is how you can write it directly as a function
/* now idx and notplayed is global- but its meant to be used only by kicker
* we cant move it inside the function definition as it will behave as local variable to the function
* and hence will be freed up once executed and you cannot maintain the state of idx and notplayed
*/
var idx = -15;
var notplayed = Math.max(input.length - 1/*player input*/ - 5, 0);
var kickers = function(all, cardinality, rank) {
return(all || 0) + (((cardinality == 1) && (notplayed-- <= 0)) ? rank * Math.pow(10, ++idx) : 0);
}
Upvotes: 0
Reputation: 9261
function(idx)
this function returns a new function function(all, cardinality, rank)
and this new function is referred by kickers variable in turn. so kickers is basically pointing at the inner function you have returned.
the only way to call your returned function is this kickers(k, cardsofrank[i], i)
Upvotes: 1