Wednesday, February 11, 2015

My Everyday Carry

This will be rare post not about IT. So, apart from programming, my other obsession is EDC, if not familiar: very good intro is here.

Current setup: phone + keys



For long time my EDC kit was phone and keys. I had special phone case, that holds cards and keys hold other essentials like CashStash for bills, Leatherman Squirt PS4 as multitool, TrueUtility pen,
even Utili-key as second multitool, as it is easier to get off keyring. I am still looking for good USB cable (I tried InCharge, but it is another story)

I like this setup very much despite drawbacks. One problem was that it is very tight and there is no place for occasional spare items: checks, change, etc. Other problem is that case holds only 2 cards and e-ticket, but ideally I need more. Final and biggest problem is that my phone gets old
and I want to change it, and wallet cases are not so popular as they used to, and there is no any decent for the new phone I want to buy. So I have to shuffle my items to fit caseless phone.

Saddleback + phone + keys



Saddleback is nice slim wallet, one of the best according to LifeHacker. Holds all cards and bills, and occasional checks. A little fat itself, even without cards, but not too fat. Phone with this wallet is almost as fat as phone with case. My biggest problem is that it is 3 pieces setup. 2 pieces - one item per pocket. With 3 pieces, 2 items should go into single pocket and there is problem that when I take out one item, another can fall out of pocket accidentally.

Crabby wallet + phone



Crabby is best for cards, super slim, holds cards firmly but still convenient to take card even from the middle. But it is not suitable for my keys as I have too many of them. I even got rid of Leatherman and CashStash (not super important as CashStash is not really needed anymore, as there is place for bills now; and Utili-key has most important tools of Leatherman).
First problem: strap is too weak and narrow. It can hold 1 or max 2 flat keys. Second: single strap locks both cards and keys, so if you need keys - cards can fall out, and if you need cards, keys are not locked and it is disturbing. Third: strapping so many keys is always annoying and difficult, and with single strap you have to do it two times more often.
Generally, Crabby is fine, but only if you have small number of keys. They warn about it in their ad, but I still decided to try. Unfortunately, they were right. Another disadvantage is that cards pocket is not zipped, so no coins or occasional small items.

Local wallet with crabby claw phone



Very good setup, wallet has 2 pockets - one puffy for keys and other - larger but tighter - for cards and bills. Both pockets are zipped separately, so everything is safe and independent. Wallet is bigger, but still comfortable for pocket.
Downsides: keys pocket is not intended for keys, so there is no any special ring or strap. I adapted slider to hold crabby claw, but it is not ideal. Also size of the keys pocket is pretty tight, and it is hard to put keys there. Taking keys out of wallet is fine and crabby claw gives some freedom, but putting them back is a little tricky. Other complain is that it is real, soft leather, which gives it great texture, but it is also a little bulkier and heavier.

Chums marsupial with crabby claw + phone



Best setup. Size is almost as small as crabby, but has special pocket for keys, which even has strap (unfortunately it is not retractable, this is my only complain). Cards pocket is zipped, so it can hold occasional change, and size is just right for cards, easily holds about 10 cards, and there is some space left. Special keys pocket is very good. It is open from the short side, It is made from some artificial fabric and is really thin and light, feels like cheap plastic though. I should see if it is durable, hopefully - it is, as I'd like to keep it.


Friday, January 23, 2015

VirtualBox DHCP gives same IP address to different machines

Usually happens after cloning VMs and problem is because there is the same MAC address. Check virtual machine network settings and change as needed.

Friday, January 2, 2015

CanJS and ClojureScript

I don't really like compiled JavaScript languages, but if I had to choose - I like ClojureScript the most. It is big friends with Om MVC framework, which is based on React.js. React is another component framework like CanJS, but is too verbose to my tastes and has less features out of the box, so I like CanJS more. Only problem is that it does not have a lot of integration with ClojureScript. But it is pretty easy to solve, because ClojureScipt and CanJS are both amazing and flexible. There is example of simple component, there is ClojureScript:

(ns myexample
  (:require [domina :refer [by-id set-html!]]
            [domina.css :refer [sel]]))

(.extend can/Component
  #js {:tag "my-component"
       :scope #js {:value 3
                   :increment #(.attr % "value" (inc (.attr % "value")))}})

(set-html! (by-id "my-root") (can/view "my-template" {}))


And HTML:

<html>
<body>
  <div id="my-root"></div>
  <script type="text/mustache" id="my-template">
    <my-component>
      Value: {{value}} <input type="button" can-click="increment" value="Increment"/>
    </my-component>
  </script>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
  <script src="http://canjs.com/release/latest/can.jquery.js"></script>
  <script src="base.js" type="text/javascript"></script>
  <script src="myexample.js" type="text/javascript"></script>
  <script type="text/javascript">goog.require("myexample");</script>
</body>
</html>



Friday, December 19, 2014

Sending data to CanJS component

Ideally, components should be independent, but sometimes it is needed to send data or call function on component from outside. It is possible to do by using observable like can.Map and listen to events on it from component like:

<script type="text/javascript">
  var observable = new can.Map({val:0});

  $(function() {
    can.Component.extend({
      tag: "my-tag",
      events: {
        "{observable} val": function(param, param2, newval){
          alert(newval);
        }
      }
    });
    $('#myTagDiv').html(can.view.mustache('<my-tag/>'));
  });
</script>



<div id="myTagDiv"></div>
<input type="button" value="Call observable" onclick="observable.attr('val', observable.val+1);">


This way all components will receive observable change event either they are sent from itself, other component or directly from JavaScript.

Wednesday, November 5, 2014

JSON converter is not working in unit tests in Grails

If calling grails.converters.JSON from unit test throws error like:

java.lang.RuntimeException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Unconvertable Object of class: my.blog.Post
	at org.codehaus.groovy.grails.web.converters.AbstractConverter.toString(AbstractConverter.java:111)
	at org.codehaus.groovy.runtime.InvokerHelper.format(InvokerHelper.java:616)
	at org.codehaus.groovy.runtime.InvokerHelper.format(InvokerHelper.java:559)


It is easy to fix this error by adding ControllerUnitTestMixin to the test definition like:

@TestMixin(ControllerUnitTestMixin)
@TestFor(BlogService)
class BlogServiceTests {
...


Friday, October 31, 2014

Grails requires restart after changes in domain class

Grails officially supports domain class reloading since version 2, but recently I found problems using it together with MongoDB GORM plugin, because it required application restart after every change to domain class.
So if Hibernate is primary GORM and Mongo is used only for some particular cases, disabling it can be a good option to make development easier.

Friday, October 17, 2014

Adding common methods to Grails domain objects

If you don't want to change your domain hierarchy, but need to add common function to multiple domains without copy/paste, one simple option is to create and implement trait. For example:
class Test implements LogTrait {
  String name
}

trait LogTrait {
  def springSecurityService

  def afterInsert() {
    log.info(this as JSON)
  }
}
Nice bonus is that events and injected services work just fine as it would be in original class.