COOKIES! This blog uses cookies!
I am completely out of control of cookies here, otherwise I would have disabled them (it is controlled by the platform).
If you don't like cookies and being tracked please leave this blog immediately.

Tuesday, 15 September 2015

Explaining closure pattern name

Live and learn. Indeed.

I'm currently reading a book about Scala and found that "closure" "design pattern" which I've been using in JavaScript for ages is actually from functional programming world, and this closure is not a whole thing, but a variable closing so called "open term".

Imagine the function:
function myFunc(a) {
  return a + b
}

The "a" variable here is a "bound variable", and it makes sense in context of myFunc. The "b" variable is a "free variable" and it is senseless in this context. The "a + b" expression here is an "open term". On the other hand if we replace the expression in myFunc with something like "a + 2" it will be a "closed term".

The name "closure" arises from the act of "closing" the function literal with the open term(s) by "capturing" bindings of its free variables.

var b = 2 //this b variable is actually a closure!
function myFunc(a) {
  return a + b
}

That's it. This variable is the "closure". And the thing is the "function literal" with the "open term".

Tuesday, 25 August 2015

String manipulations

One my friend asked me how to memorize these string manipulation functions in most of modern programming languages. Why the hek first argument in substring is zero based and second one is one based?

Everything will be easier if you realize that these offsets are not characters but something between characters. Imagine that characters in your string are separated by lines, and numbers are actually indexes of these separators rather than indexes of characters. The picture below will illustrate it well:



So, when you say “substring”, you ask computer to take a string between these separators and (a – b) will be amount of numbers to substring. If a==b, then you substring zero characters. The same about functions like insert, it inserts a string onto the separator, because you usually need to insert the string between characters, not onto them.

Monday, 17 August 2015

Reading XLSX on Android 5+

New Android Build Tools (21+) and Android 5 (ART) seems to easily fix the problem with 65K methods for Apache POI.

All you need to do is to copy the following files into libs dir of your project:
poi-3.12-20150511.jar
poi-ooxml-3.12-20150511.jar
poi-ooxml-schemas-3.12-20150511.jar
stax-1.2.0.jar
stax-api-1.0.1.jar
xmlbeans-2.6.0.jar - the hero of the day, this jar is deffective in maven repo, so it's needed to repack this jar.

See also the repo with repacked POI 3.12 jars and gradle config examples: https://github.com/andruhon/android5xlsx


Add the following into your app/build.gradle to compile your project with multi-dex to fix 65K method's limit and --core-library, to avoid the warning about javax namespace in your libs.
apply plugin: 'com.android.application'

android {
    // ...your other project settings...
    project.tasks.withType(com.android.build.gradle.tasks.Dex) {
        additionalParameters=['--core-library']
    }
}
dependencies {
    // ...deps settings...
    compile 'com.android.support:multidex:1.0.0' //enable multi-dex
}

You still might want to do a 'aavax' hack, to avoid conflicts with future android releases.

If xmlbeans not broken it would be possible to achieve the same results with just adding 'org.apache.poi:poi-ooxml:3.12' into dependencies, however it will not work straighforwardly because xmlbeans jar in maven is defective and contains duplicates of classes, these duplicates are ok for desktop JVM, but android chokes with them. So it is required to add some routine to re-pack xmlbeans and disable preDex. It will work. however the build process will be quite slow, so it is easier just to prepare jars once and put them into libs directory (as described above)

Special thanks to Heiko Johann for pointing onto new Android Build Tools features

Links:
https://github.com/andruhon/android5xlsx - config example
https://developer.android.com/tools/revisions/build-tools.html
https://developer.android.com/tools/building/multidex.html
http://www.docx4java.org/trac/docx4j - another project of reading OpenXML from Java

Previous posts:
http://blog.kondratev.pro/2014/08/reading-xlsx-on-android.html
http://blog.kondratev.pro/2014/09/further-to-my-post-from-yesterday-on.html
http://blog.kondratev.pro/2014/09/reading-xlsx-on-android-3.html

Saturday, 25 July 2015

Calculate particular weekdays in the range of dates in JavaScript

I've created a plugin for Moment JS to calculate particular weekdays in the range of dates:
https://github.com/andruhon/moment-weekday-calc

For example it would work if you need to calculate quantity business days in current financial year. The exclusion option to mind public holidays is also available.

The plugin is available in Bower and NPM as moment-weekday-calc.
npm install moment-weekday-calc
bower install moment-weekday-calc

Thursday, 25 June 2015

A little bit more on git reset and checkout

HEAD Index Workdir WD Safe?
Commit Level
reset --soft [commit] REF NO NO YES
reset [commit] REF YES NO YES
reset --hard [commit] REF YES YES NO
checkout [commit] HEAD YES YES YES
File Level
reset (commit) [file] NO YES NO YES
checkout (commit) [file] NO YES YES NO
*WD Safe means that this action will not affect files in the workdir

The order of underlying actions on HEAD, index and workdir is the following:
The reset command overwrites these three trees in a specific order,
stopping when you tell it to:
  Move the branch HEAD points to (stop here if --soft)
  Make the Index look like HEAD (stop here unless --hard)
  Make the Working Directory look like the Index

git reset file - is actually a shortcut for git reset --mixed HEAD file and does essentially unstage

Discrard all local commits on master:
git fetch --all
git log origin/master
to find the latest commit on the remote, and
git reset --hard c0mm1tID
to reset down to this commit


Source:

This presentation might also be helpful to quicly review some interesting git features:

Thursday, 16 April 2015

Redirect user directly from a webpage to a cordova / phonegap app

There's a Cordova/Phonegap plugin to define custom schemes:
>cordova plugin add https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git --variable URL_SCHEME=mycoolapp

The plugin will automatically update a platform config when the platform added or updated.

With this plugin installed custom scheme URLs like two below will invoke the application:
mycoolapp://
mycoolapp://testscreen

It is also possible to handle these URLs in your hybrid app. The handleOpenURL is called when the application is invoked via the custom scheme
/**
 * Custom schema launch plugin callback
 * @param url
 */
var handleOpenURL = function(url) {
    //your code to process the url
};

The example with AngularJS redirecting user to some particular screen of app:
/**
 * Custom schema launch plugin callback
 * @param url
 */
var handleOpenURL = function(url) {
  setTimeout(function(){
    var hash = url.replace("slingshotapp://","");
    var body = document.getElementById("mySlingshotApp");
    var app = angular.element(body);
    var $injector = app.injector();
    var $scope = app.scope();
    var $location = $injector.get('$location');
    $location.path('/'+hash);
    $scope.$apply();
  },300);
};

Please notice that if you install the plugin with the --save flag it will save the URL_SCHEME variable as `prop`, but it should be saved as a `variable` in order to be properly restored on `plugin add` or `update`. Here's the proper feature definition for config.xml:
    <feature name="Custom URL scheme">
        <param name="id" value="nl.x-services.plugins.launchmyapp" />
        <param name="url" value="https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git" />
        <variable name="URL_SCHEME" value="mycoolapp" />
    </feature>

Friday, 10 April 2015

Invoke phone Dialer from Cordova / Phonegap

There's a "tel:" schema available to invoke an external dialer from the app.

The usage example:
<a href="tel:0-800-202020">0-800-202020</a>

It works in the same way for other schemas such as "mailto:", "sms:", "geo:" and "market:".

To enable this functionality the following access permissions should be added into the config.xml:
<access origin="tel:*" launch-external="yes"/>
<access origin="geo:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="sms:*" launch-external="yes"/>
<access origin="market:*" launch-external="yes"/>