Coffeescript if else doesnt work - coffeescript

I am using coffeescript with grunt and am trying to only include JS files file pattern "*.min.js". Somehow my test is failing though and all files get included. So my if statement always returns true. How do I make this work?
getJsDependencies = ->
js_dependencies_path = path.join __dirname, "js", "dep"
paths = []
for js_file in fs.readdirSync(js_dependencies_path)
file_path = path.join __dirname, "js", "dep", js_file
console.log js_file
if js_file.indexOf ".min.js", 0 > 0
paths.push file_path
paths
I tried all kinds of combinations of js_file.indexOf but I am not having any luck with having only .min.js files included. In fact, I want to exclude them but I am stuck with string matching not the logic.
Help is appreciated!

If we add the implicit function calling parentheses to
if js_file.indexOf ".min.js", 0 > 0
we get:
if js_file.indexOf(".min.js", 0 > 0)
so you're really passing false to indexOf as its second argument and that doesn't make a lot of sense.
I think you want to say this:
if js_file.indexOf(".min.js", 0) > 0
Or since the second argument to String.prototype.indexOf is zero anyway:
if js_file.indexOf('.min.js') > 0
but even here you need the parentheses when calling indexOf to ensure that you're comparing the indexOf return value with zero.

Related

ObservableBuffer giving IndexOutOfBounds in Scala

I am mesmerized. The below code is giving me an indexoutofbound error. But if I were to delete the slashes enabling for(j <- i until tmpArray.length) it would work. I really do not understand why it is happening, and would appreciate an explanation.
for(i <- 0 until tmpArray.length)
{
// for(j <- i until tmpArray.length)
// {
if( date.getValue != null && tmpArray(i).date != date.getValue )
{
tmpArray.remove(i)
}
// }
}
You're modifying the array as you "iterate" over it.
You are actually iterating over the range 0 until tmpArray.length, which is calculated up front. At some point, you reduce the length of the array (or, I assume so, as I can't find remove on the Array class). But it's still going to continue the iteration up to whatever the last index was when you created the range.
When you uncomment the inner for block, you're making it recompute the range for each step of the outer for. And it just so happens that the j range will simply have nothing in it if i >= tmpArray.length. So it inadvertently guards against that failure.
This is very C-style (imperative) code. It looks like all you're trying to do is remove some items from an array. That's what filter is for.
val result = tmpArray.filter { d =>
if(date.getValue != null && d != date.getValue) false else true
}
This creates a new array (result) by passing an anonymous function to tmpArray.filter. It will pass each item in the array to your "predicate", and if it returns true, it'll keep that item in result, otherwise it will omit it.
You should note that I avoided saying "loop". Scala's for isn't for making loops. It's actually syntax sugar for calling methods like foreach and map. Google "scala for comprehensions" for more detail.
If you insist on creating a C-style loop using indexes and a loop variable, you'll want to use while, so that you can check if i < tmpArray.length each time.

Ignoring an output parameter from vDSP

When using vDSP to perform some speedy calculations, I often don't care about one of the output parameters. Let's say I'm finding the index of an array's maximum value:
var m:Float = 0
var i:vDSP_Length = 0
vDSP_maxvi(&array,
1,
&m,
&i,
vDSP_Length(array.count))
Ideally, I'd like to get rid of m altogether so that vDSP_maxvi fills i only. Something like:
var i:vDSP_Length = 0
vDSP_maxvi(&array,
1,
nil,
&i,
vDSP_Length(array.count))
But of course this doesn't work ("nil is not compatible with expected argument type 'UnsafeMutablePointer<Float>'"). Is there some sort of argument I can send to these kinds of methods that says "ignore this parameter"? Thanks for reading.
Except for documented cases where a null argument is accepted, you must pass a valid address. There is no argument value that tells vDSP to ignore the argument.

Splat for removing an item from an array

Although I know about splats, still I can't quite grasp the last line from the following code:
class Borrowable extends Decorator
constructor: (#libraryItem) ->
removeBorrower: (borrower) ->
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
Btw, this code was copied from https://github.com/aksharp/Design-Patterns/blob/master/CoffeeScript/Decorator.coffee
Im assuming this is Destructuring Assignment, still I can't quite get my head around what's it's happening behind the scenes.
Could you help clarify this?
Let's have a closer look at the last line:
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
I'm not sure if this form counts as Destructuring Assignment, probably it is.
First, it calls #borrowers.indexOf(borrower) to check that borrower is present inside of the #borrowers array and to get it's index.
It's conventional to use borrower in #borrowers form instead of #borrowers.indexOf(borrower) > -1, but in this case we need index of an element as well.
If borrower is present in #borrowers, it gets the part of the #borrowers array between indexes t and t
#borrowers[t..t]
which is the [borrower], and assigns it to the empty array [], thus removing the borrower from #borrowers array.
Here is js-like equivalent of this assignment:
#borrowers.splice t, 1

More elegant coffeescript loop

JS:
for(i=this.current.arr.length;i<this.counterLength;i++){
dosomthing();
dosomethingelse();
}
COFFEE:
i = #current.arr.length
while i < #counterLength
dosomthing()
dosomethingelse()
i++
I know coffeescript has great loop syntax candy, but I can't find a more elegant way of writing it than this. Is there a more coffeescripty way of doing this?
I know about:
for currentArr in current.arr
//and
for currentArr, 1 in current.arr
but i needs to start at #currentLength and not 0
The [..] operator is what you are looking for:
start = this.current.arr.length
end = this.counterLength
for [start...end]
dosomthing()
dosomethingelse()
No need to predefine start and end, I just used it to make the code a bit clearer. Note that if start is greater then end, then it will go backwards.
Actually you need [...] operator, because you used < instead of <= in the code. The [...] operator excludes the last element.

coffeescript not implicitly returning "false"

I am trying to add a method to the String primitive type/class where I can extra params from a URL string
String::getUrlParams = -> # line 1
false unless ( params = #.split('?')[1] ) # line 2
# ...
In Chrome console, when I deliberately call this method with a string of URL without params, I expect it to just return false.
"http://dns.com/".getUrlParams();
but it goes pass through line 2.
if I change line 2 to
return false unless ( params = #.split('?')[1] ) # line 2`
then it does return false and stops the function at line 2
Any idea why coffeescript isn't returning false and halts the function in the first version?
Thank you
Coffeescript returns only the last function statement. If something follows some statement, that you want to return in middle of function, then you should do that explicitly.
--Short thoughts--
In short - Coffeescript compiler is not that smart, to predict, where you may want or may not want to return something. And same applies to most compilers now days. Also it's non-smartiness avoids most of mistakes, which would be caused because of premature return.