Thursday, February 27, 2014
Monday, February 24, 2014
Monday, February 17, 2014
Plain text screencast
“How do you install a foobar-quux?”, you hear it from the other side of the desk. “It’s easier to do than to explain”, you respond grabbing your keyboard. A few lines in the terminal and it’s done. You hesitate for a moment to write a neat script of what you’ve just done. But it’s not that easy, because… And it’s not worth it once you’re done. Until you hear the same question again in a week, “How did you install that foobar thing? It looked so easy, but I forgot.”
If you had a really lightweight screencast tool at hand which does nothing fancy, no screen resolution and frame rate settings. Just record what I do in the terminal.
The funny thing is this simple tool exists. It’s pretty old, actually, its first version was released in 2000. The original one is called ttyrec. It has quite some spinoffs. You can even upload it to the web and replay in the browser. I found more sites offering this service
My favorite one is Shelr.tv where you can change the replay speed.
If you had a really lightweight screencast tool at hand which does nothing fancy, no screen resolution and frame rate settings. Just record what I do in the terminal.
The funny thing is this simple tool exists. It’s pretty old, actually, its first version was released in 2000. The original one is called ttyrec. It has quite some spinoffs. You can even upload it to the web and replay in the browser. I found more sites offering this service
My favorite one is Shelr.tv where you can change the replay speed.
Saturday, February 1, 2014
Rules to write functional Scala code and stay sane
Use only cases classes from the OOP world
Well, with some exceptions that will follow soon. But the baseline is: no regular classes, no inheritance. A case class can be considered an abstract data type, so it can serve as a container. Another use case for them can be seen as a little weird form of currying.val people = List("Bob", "Mary")
// functional
def join(separator: String, list: List[String]): String = {
list mkString separator
}
def joiner(separator: String) = {
(list: List) => join(separator, list)
}
joiner(",")(people)
// with a case class
case class Joiner(separator: String) {
def join(list: List[String]) = {
list mkString separator
}
}
Joiner(",") join people
Use traits only to simulate union types
There are cases when an instance can be one of two types, for example a tree node can be either a branch, or a leaf node. If we follow the above rule of using only case classes, we’ll be in trouble. This is where we can use a trait shared by some case classes.trait TreeNode {}
case class Leaf(value: String) extends TreeNode {}
case class Branch(left: TreeNode, right: TreeNode) extends TreeNode {}
It’s OK to add methods to the trait if they would be shared by the case classes. (It would be difficult to use this tree example, because that would lead us to the field of recursive data types.)trait NDArray {
def rank: Int
def isScalar = {
rank == 0
}
}
case class Scalar(value: Double) extends NDArray {
def rank: Int = 0
}
case class Matrix(elems: List[Any]) extends NDArray {
def rank: Int = {
elems.headOption match {
case Some(x: NDArray) => 1 + x.rank
case None => 1
case Some(_) => 1
}
}
}
Matrix(List(4)).rank // => 1
Matrix(List(Matrix(List(5)))).rank // => 2
Scalar(5).isScalar // => true
Matrix(List(4)).isScalar // => false
Avoid class level values
It’s a sign that you are about to add an unwanted dependency which will be difficult to inject/mock later. A typical usage to avoid is reading configuration values in the middle of some method.case class BadGreeting(firstName: String, lastName: String) {
val person = Person(firstName, lastName)
val location = Configurator getConfigValue "greeting.location"
def greetWith(greeting: String) = {
greeting + ", " + person.fullName + " in " + location
}
}
// That should be refactored to this class
case class GoodGreeting(person: Person, location: String) {
def greetWith(greeting: String) = {
greeting + ", " + person.fullName + " in " + location
}
}Pass an argument object instead of too many arguments
The rules so far prefer explicit to implicit. It may lead to a loooong list of arguments, though. The cure for this is to create a case class for those arguments. It’s a matter of personal taste how many arguments you consider too many. I would say, don’t have more than three.
Subscribe to:
Posts (Atom)