code

Its all just ones and zeroes isn't it? 
Filed under

ubuntu

 

An Option class in Scala with three states: Unknown, Known.Some, Known.None

Scala's library includes a class called Option which can be used to represent an optional value, instead of using null, it has two states: None and Some[T], so either it has a value, or it doesn't.

I needed a class to represent three states (tristate): Unknown (you don't know the value), Known.Some (you know the value), Known.None (you know there is no value).  An example of where you'd use this might be for a property like radioType of class car.  You might use a tristate value to indicate that you don't know the type of the radio on this car, or that you do know the type of radio, or that there is no radio.

Code:



/*
 * Similar to Option[T], but represents three states: known-some, known-none, and unknown
 */
sealed abstract class KnownUnknown[+T] extends Product {
  def isEmpty : Boolean
  def get : T
  
  def isDefined : Boolean = !isEmpty
}

/*
 * Represents the unknown state
 */
case object Unknown extends KnownUnknown[ Nothing ] {
  def isEmpty = true
  def get = throw new NoSuchElementException("Unknown.get")
}

/*
 * Represents the known state (either you know its Some(T) or its None)
 */
final case class Known[+T](_value : Option[T]) extends KnownUnknown[T] {
  if ( _value == null )
    throw new NullPointerException
  
  def this(value : T) = this(Some(value))
  
  def isEmpty = false
  def get = _value.get
}


And a few basic tests:



class KnownUnknownTest extends TestCase("KnownUnknown") {
  def testSome = {
    var value : KnownUnknown[Int] = null
    value = new Known(5)
    
    value match {
      case Known(known) =>
        known match {
          case Some(number) => assertEquals(5, number)
          case None => fail()
        }
      case Unknown => fail()
    }
    
    assertEquals(5, value.get)
  }
  
  def testNone = {
    var value : KnownUnknown[Int] = null
    value = new Known(None)
    
    value match {
      case Known(known) =>
        known match {
          case Some(number) => fail()
          case None =>  // good
        }
      case Unknown => fail()
    }
    
    try {
      value.get
    }
    catch {
      case e:NoSuchElementException => // good
      case _ => fail()
    }    
    
    assert(true) // so we get picked up as a test
  }

  def testUnknown = {
    var value : KnownUnknown[Int] = null
    value = Unknown
    
    value match {
      case Known(known) => fail()
      case Unknown => // good
    }
    
    try {
      value.get
    }
    catch {
      case e:NoSuchElementException => // good
      case _ => fail()
    }
    
    assert(true) // so we get picked up as a test
  }
}


Filed under  //   option   scala   tristate   ubuntu  

Comments [0]

Writing a Bash script that knows its own location

I wrote a small bash script the other day, on Ubuntu, to launch a java program in a jar file.  My first attempt worked, but it only worked if you invoked the script from the folder the script was in, but if it was invoked from any other folder, it would fail, because it was referencing the jar file with a relative path, and that path was relative of the location the script was invoked from, not the location it resided in.

Here's an example script:

#!/bin/bash
LSOF=$(lsof -p $$ | grep -E "/"$(basename $0)"$")
MY_PATH=$(echo $LSOF | sed -r s/'^([^\/]+)\/'/'\/'/1 2>/dev/null)
MY_ROOT=$(dirname $MY_PATH)
java -cp $MY_ROOT/../target/yourjar-1.0-SNAPSHOT-jar-with-dependencies.jar com.acme.YourClass

I did find one edge case where this doesn't work.. If the script is in a folder with the same name as the script, it gets messed up.

Filed under  //   bash   howto   java   ubuntu  

Comments [0]

Using "citext" in PostgreSQL for case insensitive comparisons

I think its new in PostgreSQL 8.4, there is a new field type called citext, which stands for case insensitive text.  Currently on Ubuntu 9.10 its in the PostgreSQL contrib package, which often serves as a testbed for features before they are adopted into PostgreSQL proper.

Using citext ensures that all comparisons are case insensitive, which includes referential integrity on inserts, updates and deletes, and SQL queries for lookups for example, which I think will work well for those fields that should always be compared case insensitive.

Although citext (and probably many other modules) are not listed on the contrib page, they are included, you can see them in the complete file list.

Steps to install on Ubuntu 9.10 (Karmic Koala):

# Install the contrib package
sudo apt-get install postgresql-contrib-8.4
# Add the citext module to a database of your choice
psql [username] -d [databaseName] -f /usr/share/postgresql/8.4/contrib/citext.sql

Where in this case /usr/share/postgresql/8.4 is the PostgreSQL SHARE_DIR folder.

Now you can use the field citext instead of text.  If you'd like to use citext on Ubuntu 9.04 Jaunty (which only includes PostgreSQL 8.3), then check out Mark's post about installing PostgreSQL 8.4 on Ubuntu 9.04.

Filed under  //   howto   linux   postgres   postgresql   ubuntu  

Comments [0]