Friday, December 28, 2012

Interactive Scala Console (REPL) for Play Application

Since I know Ruby/Rails so well, I constantly compare that technology stack with Scala/Play.

Ruby has IRB (interactive ruby shell).  Scala has REPL.

When developing a Rails application, I frequently use the Rails Console to debug Rails project code.  Execute the following command from the OS shell, e.g., Bash, in your Rails project:

rails c

The default environment is development, but you can also open the rails console for test or production (or any custom environment you create)

Rake is the Ruby-based build tool for Rails apps.

Similarly, SBT is the scala-based build tool used for Play applications.

SBT is typically used to compile and execute a Scala scripts containing dependency declarations or other sbt settings.

I created a script to start SBT for my project that looks like:


sbt.sh


java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=512m -Xmx2048M -noverify -jar -Dcom.company.project.common.util.devmode=yes $HOME/opt/sbt/bin/sbt-launch.jar "$@"

That allows me to run commands like:

update
gen-idea
project project_name
clean
compile

But I wanted to actually run scala commands and exercise application APIs.

I'd get errors like the following:

SBT Console

$ sbt-no-repl.sh
Listening for transport dt_socket at address: 8000
[info] Loading project definition from /hs/dev/company/project
[info] Set current project to ap (in build file:/hs/dev/company/)
project:master:5.0-SNAPSHOT> 
project:master:5.0-SNAPSHOT> var allProducts = new ListBuffer[String]()
[error] Not a valid key: var (similar: start, run, target)
[error] var allProducts = new ListBuffer[String]()
[error]    ^
project:master:5.0-SNAPSHOT> import collection.mutable.ListBuffer
[error] Not a valid key: import (similar: port)
[error] import collection.mutable.ListBuffer
[error]       ^


... until I learned how to startup the Scala REPL, defining the dependencies that should be on the classpath, and adding that to my SBT script:

sbt.sh

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=512m -Xmx2048M -noverify -jar -Dnet.tstllc.common.util.devmode=yes  -Dsbt.main.class=sbt.ConsoleMain -Dsbt.boot.directory=/Volumes/HoneyBadger1TB/Users/lex/.sbt/boot $HOME/opt/sbt/bin/sbt-launch.jar "$@"


SBT (with REPL) Console

$ sbt
Listening for transport dt_socket at address: 8000
[info] Set current project to default-3bc954 (in build file:/Volumes/HoneyBadger1TB/Users/lex/.sbt/boot/ivy-console/)
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
Type in expressions to have them evaluated.
Type :help for more information.

scala> var allProducts = new ListBuffer[String]()
<console>:7: error: not found: type ListBuffer
       var allProducts = new ListBuffer[String]()
                             ^

scala> import collection.mutable.ListBuffer
import collection.mutable.ListBuffer

scala> var allProducts = new ListBuffer[String]()
allProducts: scala.collection.mutable.ListBuffer[String] = ListBuffer()

scala> allProducts += "1"
res0: scala.collection.mutable.ListBuffer[String] = ListBuffer(1)

scala> allProducts += "2"
res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(1, 2)

scala> 


References

http://www.scala-sbt.org/
http://www.scala-sbt.org/release/docs/Detailed-Topics/Scripts.html
http://www.playframework.org/
http://rake.rubyforge.org/

Special thanks to Kyle Unverferth!

Sponsor Ads


Thursday, December 27, 2012

Fixing the TimeZone in OSX (Mountain Lion)

My timezone got misconfigured at some point and my timestamps have been eight hours off.

I tried setting the timezone as described in articles like this:

http://www.ehow.com/how_4660998_change-zone-mac-os-x.html

And using system commands:


~ $ sudo systemsetup -settimezone  America/New_York
Set TimeZone: America/New_York
~ $ sudo systemsetup -gettimezone
Time Zone: Europe/Brussels



I tried suggestions listed here:
http://www.keiths-place.com/blogs/keith/2007/gmt-timezone-problem-mac-os-x

https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/systemsetup.8.html



But my timezone never changes from Europe/Brussels.


Today, I had to study log files to determine if some scheduled jobs actually ran when they were supposed to.

So, it was time to tackle the timezone misconfiguration.

Symptoms: The time displayed on the top apple menu bar appeared correctly, e.g., 11:47 AM, however any time stamp, run using the system date command, would display 17:47.


~ $ echo `NOW`
20121227-175329   
~ $ sudo cp /usr/share/zoneinfo/Europe/Brussels /usr/share/zoneinfo/Europe/Brussels_ORIG
~ $ sudo cp /usr/share/zoneinfo/America/New_York /usr/share/zoneinfo/Europe/Brussels 
~ $ echo `NOW`
20121227-115421

Here's my NOW alias:

alias NOW='echo "`date +%Y%m%d-%H%M%S`"'


I also had to go to the System Preferences | Date & Time and uncheck "Set date and time automatically" and set the time.  I also unchecked the "Set time zone autotmatically using current location".



~ $ ls -l /etc/localtime
lrwxr-xr-x  1 root  wheel  36 Dec 27 17:39 /etc/localtime -> /usr/share/zoneinfo/America/New_York
~ $ echo `NOW`
20121227-173935
~ $ sudo systemsetup -gettimezone 
Time Zone: Europe/Brussels



~ $ sudo systemsetup -gettimezone 
sudo: timestamp too far in the future: Dec 27 11:54:17 2012

WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type "man sudo" for more information.

To proceed, enter your password, or type Ctrl-C to abort.

Password:
Time Zone: Europe/Brussels
~ $ sudo systemsetup -gettimezone 
Time Zone: Europe/Brussels

I not pleased that the system thinks my timezone is Europe/Brussels and that I will have to manually adjust for daylight savings time...


~ $ sudo systemsetup -settimezone  America/New_York
Set TimeZone: America/New_York
~ $ sudo systemsetup -gettimezone
Time Zone: Europe/Brussels



... but at least my system time display (xclock) and timestamps work :-/



Sponsor Ads


Sunday, December 16, 2012

Convert from List[Any] to Array[String] in Scala





Convert List[Any] to Array[String]

scala> val stringAry: Array[String]  = (List("a", 1) map (_.toString)).toArray
stringAry: Array[String] = Array(a, 1)



Create typeOf method to determine the type of each element in array

scala> def typeOf[T: Manifest](t: T): Manifest[T] = manifest[T]
typeOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]



Print results

scala> stringAry.foreach( i => println(typeOf(i)) )
java.lang.String
java.lang.String



References





Sponsor Ads


Sublime Text2 Preferences Menu Disabled

When I install ST2 using what seems reasonable, i.e., dragging the ST2 icon to the Applications icon link in the install folder, my ST2 Preferences menu becomes helplessly disabled.

To fix this, I uninstalled ST2 and instead of dragging the ST2 icon to the link, I drag it to the real Applications folder in the Finder.

If anybody has a more elegant solution, please share.



So far, so good... Still seeing the ST2 | Preferences menu.


ST2 is a great text editor, but it's got its rough edges.


Sponsor Ads


TextMate-like Recording of Macros using Sublime Text2

Today, I tried to record a macro and noticed that both the Tool | Record Macro  and the Tools | Playback Macro  menu options both had CTL+Q as their key binding, which made recording and playing back macros not fun.

So, I decided to change the key binding to that which my trusty TextMate editor uses.

However, the Preferences menu option for ST2 was disabled.

After mucking around for a minute, I decided to uninstall ST2 and do a clean install.

That worked nicely.

I then went to ST2 | Preferences | Key Bindings - Default and changed the key bindings for the following, from "ctrl+q" and "ctrl+shift+q" to "super+alt+m" and "super+shift+m" for toggle_record_macro and run_macro, respectively.



{ "keys": ["super+alt+m"], "command": "toggle_record_macro" },
{ "keys": ["super+shift+m"], "command": "run_macro" },

Sponsor Ads


Monday, December 10, 2012

Getting ANSI (color) escape codes to render in Windows terminal

Today, I had the opportunity to help a colleague on the test team get his terminal to display colorized text properly so that he could more effectively read his Cucumber tests results.

At first, I installed CYWIN on his Windows 7 (64bit) box because CYGWIN's terminal window shells, e.g., RXVT terminal, display the text using color codes, unlike the stock MS Windows terminal/console application.

Here are some things we learned:

  • RBENV does not install easily under CYGWIN
  • It's better to go with the stock Ruby install from CYGWIN
  • Windows terminal emulators run a little faster than CYGWIN terminal applications


So, we ended up installing CONSOLE from http://sourceforge.net/projects/console/

Console is a Windows console window enhancement. Console features include: multiple tabs, text editor-like text selection, different background types, alpha and color-key transparency, configurable font, different window styles

Now, he's can read his colored Cucumber test results in the Console and he has an install of CGWIN, which he can use for nice unix'y command line fu.

Sponsor Ads


Friday, December 7, 2012

Reinstalling MySQL on Mac 10.7 (Lion)

Had to reinstall MySQL because my mysql install scripts were failing because mysql was unable to drop databases.

Not sure what got misconfigured but I figured it would take less time to just reinstall MySQL.

Steps to re-install MySQL


1. Download latest mysql package from http://www.mysql.com/downloads/mysql/

2. Run install programs


3. Verify MySQL icon added to Preferences Pane
4. Start MySQL on reboot

Done.

Now, MySQL is installed and ready to use.

Sponsor Ads


Upgrading from IntelliJ 11 to IntelliJ 12

When I installed IntelliJ 12, I chose to import settings from the IntelliJ 11 install.

Note: I did not uninstall IntelliJ 11, yet.

Next, run sbt and on the sbt console, run update and then gen-idea

Every time I opened IntelliJ 12 it would pop up a few annoying notifications about the fact that I had not configured Android development plugins.

So, I uninstalled IntelliJ 12 and chose not to import settings.

Now, the problem was that none of my Scala source files had Scala syntax coloring.  Then, I got a popup griping about the fact that the Scala facets were not installed/configured.

So, I got the IDEA Scala Plugin for IntelliJ 12 (see URL below), went to IntelliJ Preferences | Plugins and clicked the "Install plugin from disk..." button.


Preferences Modifications

Change the color theme in IntelliJ Preferences | Appearance to the new Darcula theme

Change Tab Size (and Indent) to 2 spaces in Code Style | General

Check Editor | Appearance "Show line numbers"


References


Get IntelliJ 12 here: http://www.jetbrains.com/idea/download/

Get latest Scala Plugin for IntelliJ here:  http://confluence.jetbrains.net/display/SCA/Scala+Plugin+Nightly+Builds+for+Leda


Sponsor Ads


Wednesday, November 21, 2012

Configure Sublime Text 2 (ST2) JSHint plugin


brew install node
brew install npm
npm install jshint -g

Install ST2 Package Control:  http://wbond.net/sublime_packages/package_control/installation

Restart ST2
CMD-Shift-P opens Package Control dialog (OSX)
Type:  Install  and hit enter  << That will select Package Control:  Install Package
Type:  sublime-jshint and hit enter

Now, when you edit a javascript file and save it, you will get the following error message:

Error trying to parse build system: No data in ~/Library/Application Support/Sublime Text 2/Packages/JSHint/JSHint.sublime-build:1:1

cd /Volumes/HoneyBadger1TB/Users/lex/Library/Application\ Support/Sublime\ Text\ 2/Packages
ln -s Sublime-JSHint JSHint


Now, when you save files in ST2 JSHint will display messages at the bottom of your editor window..


Sponsor Ads


Thursday, November 15, 2012

Calculating totals from sub lists using Scala

Requirements

Given a list of users' names and permissionIds
I want a total count of each permissionId
So that I can see which permissions are required most frequently


Given the following data about two users (Alice and Bob)...


{"users":[
  {"title":"Alice", 
   "permissionIds":[1,2]
  },
  {"title":"Bob", 
   "permissionIds":[2,3]
  }
]}

I want to map those users' permsission Ids (1, 2, 3) to each one's count.

permissionId  total
1                    1
2                    2
3                    1


Solution

Here's how to accomplish this in Scala:



scala> case class User(name: String, permissionIds: List[Int])
defined class User

scala> val user1 = User("Alice", List(1, 2))
user1: User = User(Alice,List(1, 2))

scala> val user2 = User("Bob", List(2, 3))
user2: User = User(Bob,List(2, 3))

scala> val users = List(user1, user2)
users: List[User] = List(User(Alice,List(1, 2)), User(Bob,List(2, 3)))

scala> val permissionIdTotals = users.map(_.permissionIds).flatten.groupBy(identity).mapValues(_.size)
permissionIdTotals: scala.collection.immutable.Map[Int,Int] = Map(3 -> 1, 1 -> 1, 2 -> 2)




Here's how the permissionIdTotal calculation is broken down:



scala> users.map(_.permissionIds)
res0: List[List[Int]] = List(List(1, 2), List(2, 3))

scala> users.map(_.permissionIds).flatten
res1: List[Int] = List(1, 2, 2, 3)

scala> users.map(_.permissionIds).flatten.groupBy(identity)
res2: scala.collection.immutable.Map[Int,List[Int]] = Map(3 -> List(3), 1 -> List(1), 2 -> List(2, 2))

scala> users.map(_.permissionIds).flatten.groupBy(identity).mapValues(_.size)
res3: scala.collection.immutable.Map[Int,Int] = Map(3 -> 1, 1 -> 1, 2 -> 2)


Retrospective

Note that I did not use variables to store temporary values;  It uses a series of chained function calls to arrive at the final calculation.

Given a set of input values, the results will always be the same.  There are not side effects.

The converse of functional programming is imperative programming.

Imperative programming tends to be easier to understand, but requires more lines of code and may not be safe to use when attempting to satisfy concurrent programming requirements.

Sponsor Ads