Mysterious 404 responses with foursquare OAuth2 + google-app-engine

I’ve done a lot of work on my aforementioned foursquare / last.fm mashup project, which I’m still not exactly ready to start crowing about, but whose source is, as ever, available.

I’m currently hitting a bunch of problems in getting my Python code to work while it’s deployed out to Google’s appspot.com production environments.  I’ve been able to authenticate successfully against foursquare from my local environment, following their straightforward instructions, but every time I try to run the same code out in Google’s cloud, once I hit the point where I retrieve an access code from foursquare and make a request for a legit session token, this is what I wind up with:

    HTTP blarg, feh
    Traceback (most recent call last):
    File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 545, in dispatch
      return method(*args, **kwargs)
    File "/base/data/home/apps/s~how-you-been/0-2-4.357616581640073459/whence.py", line 97, in get
      accessCode = self.getFoursquareAccessToken(code)
    File "/base/data/home/apps/s~how-you-been/0-2-4.357616581640073459/howyoubeen/Foursquare.py", line 49, in getFoursquareAccessToken
      httpResponse = urllib2.urlopen(url)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 126, in urlopen
      return _opener.open(url, data, timeout)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 400, in open
      response = meth(req, response)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 513, in http_response
      'http', request, response, code, msg, hdrs)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 438, in error
      return self._call_chain(*args)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 372, in _call_chain
      result = func(*args)
    File "/base/python27_runtime/python27_dist/lib/python2.7/urllib2.py", line 521, in http_error_default
      raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)

Dang it!  My initial instinct is that I’m hitting a timeout in Google’s cloud environment, but are they honestly passing a 404 back to my stack at that point?  (I suspect, as an alternate explanation, something about my error-handling handlers are deficient.)

While looking into this I’ve stumbled upon a few Python OAuth2 libraries, about which OAuth2 isn’t exactly rocket science, but if the libraries have a decent interface and can overcome this issue, maybe I’ll give them a shake.  (On the js side of the world I’ve been having a few similar issues, where I’d like to move to an open-source library but the ones I’ve seen make odd assumptions about the execution environment.)

Another possibility I’ve considered is that there’s some sort of SSL wildcard issue at play, as suggested by this stack overflow answer which foursquare has bravely elected as their replacement for tech support.  But for now, it is a mystery.

Generating weighted-probability lists in Javascript

js-weighted-list test page screenshot

I’ve made a good deal of progress on my Google App Engine application, about which more later.  During the course of it, I started to keenly feel the need for a weighted random list.  That is, I have a list and want to select a random sample from it, but it has an unequal (weighted) probability distribution; I want some of the items to be selected more frequently than others.  I also need to modify the weights depending on what else is going on in the program (eg, in response to user input or web service results.  Also, this is all happening on the front-end, so it needs to work in javascript.

Poking around for a while I couldn’t find anything obviously relevant to this, but I did find a pretty good breakdown of the problem and the algorithm to follow in this Stack Overflow answer.  This implementation makes use of a heap in order to enable a binary search on the probability space.  While digging through to understand it, I wound up reimplementing the thing in Javascript, and then made a bunch of improvements to the API for it.  It’s pretty basic and doesn’t have any particular dependencies, so I’m releasing it as its own library, js-weighted-list.

It is available on github under the MIT license.  There are still several things I need to improve with it, in particular it’s severely under-tested, but it’s decently documented and immediately usable for what I need it to do.

Using pyjade with webapp2 on Google App Engine

And now for something completely different. I got a little distracted again by an idea for a simple social networking mashup I’ve had and decided that the best place to deploy it would probably on Google App Engine.  App Engine supports Scala and I’ve seen one or two positive reports about using Scalatra on it, so I thought it wouldn’t be too hard to spin something up quickly using my existing code.

It turned out not to be as easy as that, unfortunately; I may try to elaborate on the reasons in a later post, but it seems to come down to Scalate always checking the filesystem for its template routines.  In any event, I found that I was spending a lot of time trying to glue weird bits of infrastructure to one another rather than working on my idea.

With that in mind, I decided to start over in Python, and of course as my first task I spent a long time glueing random bits of infrastructure together.  In this case I’ve been successful, though, so here’s a brief writeup on getting Jade templates to work with Google App Engine and Google’s webapp2 in python.

1. Add dependencies to include webapp2′s jinja2 module in your project.

This is as simple as adding this bit of code to app.yaml:

libraries:
- name: jinja2
  version: latest

2. Install pyjade in your environment.

I’ve been using a layout similar to the one mentioned in this Stack Overflow answer.  It’s puzzling that Google doesn’t really mention anything about a standard way to get libraries and stuff from the wider Python ecosystem installed in a development environment, but essentially I set up a virtualenv, ran pip install pyjade, and then symlinked the pyjade directory from the virtualenv lib directory into the project’s src directory.

3. Add a custom Jinja2 factory.

This is where the magic happens.  We write a factory function, jinja2_factory, whose purpose is to add pyjade’s included Jinja2 extension into the Jinja2 instance’s Environment.

  def jade_factory(app):
    j = jinja2.Jinja2(app)
    j.environment.add_extension('pyjade.ext.jinja.PyJadeExtension')
    return j

Then, in our handler’s jinja2 method, we pass along the factory method to it:

  @webapp2.cached_property
  def jinja2(self):
    return jinja2.get_jinja2(app=self.app, factory=jade_factory)

(This is based on moraes’s Stack Overflow answer here.)

4. Use the factory and get a template.

Here’s the full source code for a simple “hello world” app. I’m following the examples on Google’s jinja2 page and creating a JadeHandler subclass of RequestHandler.

import os
import webapp2
from webapp2_extras import jinja2

class JadeHandler(webapp2.RequestHandler):
  # Per http://stackoverflow.com/a/7081653/87990
  @staticmethod
  def jade_factory(app):
    j = jinja2.Jinja2(app)
    j.environment.add_extension('pyjade.ext.jinja.PyJadeExtension')
    return j
  
  @webapp2.cached_property
  def jinja2(self):
    return jinja2.get_jinja2(app=self.app, factory=JadeHandler.jade_factory)

  def render_response(self, _template, **context):
    # Renders a template and writes the result to the response.
    rv = self.jinja2.render_template(_template, **context)
    self.response.write(rv)

class MainPage(JadeHandler):
  def get(self):
    context = {'message': 'Hello, world!'}
    self.render_response('index.jade', **context)

app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Caveat

I’m by no means an expert in Google App Engine, and I’m a little worried that there’s something badly inefficient or similarly wrong about this approach. In particular, I’m hoping the returned templates are cached, but I’m not certain, and I’ve seen reports that Jinja2 Environment creation is an expensive operation on GAE. More to the point, pyjade seems to work as a preprocessor for Jinja2, so it would obviously be better not to need to run it for every request. In any event, this does at least find jade templates and render them properly as HTML.

Edit: as usual, the current code is available on GitHub.

The cake falls

(I’m running out of snappy cake-related puns here, but I’m saving “the cake is a lie” for a special occasion.)

So after thinking about my interface / implementation dilemma for a while (recap: I’m aiming to separate out the implementations of hexmap from their interface), I decided to approach it from a Java vantage point and see how I’d implement the same thing in Java.  The immediately obvious thing that jumped out at me was that the specific problem I was dealing with was sort of a classic application of plain old vanilla inheritance from an abstract class.  Having drunk deeply from the well of Spring over my last several years of Java experience, plain old inheritance had begun to seem in some ways like a quaint relic of a bygone era (having been replaced in many cases by service composition).

At any rate, a quick bit of refactoring to get rid of traits altogether got me back to a fairly sane codebase, where I’ve got this:

abstract class HexMap (h: Int, w: Int) {
  val height = h
  val width = w
  // This is where the magic happens
  def data(addr: Address): HexData
}
abstract class HexData(a: Address) {
  def toJson(): JObject = JObject(List()) // default: empty JSON object
}

case class ColorData(a: Address, color: String) extends HexData (a) {
  override def toJson(): JObject = {
    ("color" -> color)  // json {"color": "foo"} via JsonDSL
  }
}
class RandomColorMap(h: Int, w: Int) extends HexMap(h, w) {
  private val store: Map[Address, ColorData] = createRandomMap()
  def data(addr: Address): ColorData = {
    store(addr)
  }
  // Note, we're able to access width and height here
  private def createRandomMap(): Map[Address, ColorData] = {
    val pairs = for (x <- 0 until width; y <- 0 until height) yield {
      val addr = Address(x, y)
      addr -> ColorData(addr, randomColor())
    }
    pairs toMap
  }
}

I will come back and revisit this later; I’m certain there’s a way traits could be useful in this code, but for now I’m leaving them aside and pressing on with more actual program functionality.

As far as that is concerned, my next worry is persisting the hexmap the user sees in their Scalatra session, so that when the user asks for a random path from the server, he or she gets one within the actual bounds of the actual map he or she is seeing. The Scalatra session docs make this look fairly straightforward; we’ll see.

More delicious cake

I’ve made some progress on both the client and server sides of the hexmap project.  On the client side, there’s now some code to highlight tiles (though it’s still imperfect).  I’ve also updated the map representation some, so it looks like this:

[ {"x":1, "y":1, "data":{"color": "yellow"}},
  {"x":1, "y":2, "data":{"color":"white"}},
  {"x":2, "y":1, "data":{"color":"white"}},
  {"x":2, "y":2, "data":{"color":"lightgreen"}} ]

The idea is that the data object will expand to have more game or application-specific data.  I’m not 100% sure that moving to a sparse representation (versus a 2d matrix) is a good idea, but I don’t think it will hurt me all that much, and it shouldn’t be too difficult to change back if I need to.

On the Scala side of the fence, I’m using the lift-json library to perform serialization to JSON.  I’m still not sure I’ve structured this in a way that really makes sense in the long-term.  One thing I’m hoping to achieve with this project is to wind up with a fairly abstract, generic hexmap library which can be augmented by application-specific code to implement a particular game or the like.  So I’m trying to partition off some of the specific stuff, such as in this case tile colors, into its own conceptual space, but I’m not sure I’m doing it idiomatically.

In particular, I think I’m hitting a slight impedance mismatch between Java and Scala revolving around traits, self-type declarations, and the Cake Pattern versus interfaces and Spring-style dependency injection.  I’d like to separate out the interface of a hexmap from the implementation used to actually implement the hexmap, so what I have is this:

class HexMap (h: Int, w: Int) {
  // Every instance of a HexMap will be mixed in with a HexStore
  self: HexStore =>

  val height = h
  val width = w

  def hex(x: Int, y:Int): Hex // Return data for a specific cell
}

And then HexMapStore implementations derive from this:

abstract class HexData(a: Address) {
  def toJson(): JValue // return a json representation of this data
}
abstract trait HexStore {
  def data(addr: Address): HexData  // Get the specific data from addr
}

My idea for this was that there might be one implementation which uses a MongoDB store, one which uses an in-memory map, etc. The fundamental operation, though, is to pass in a grid address and retrieve the data for that cell. The actual implementation I’ve got now is this:

case class ColorData(a: Address, color: String) extends HexData (a) {
  def toJson(): JValue = {
    ("color" -> color)  // json {"color": "foo"} via JsonDSL
  }
}
trait RandomHexMapStore extends HexStore {
  private lazy val store: Map[Address, ColorData] = createRandomMap()
  def data(addr: Address): ColorData = {
    store(addr)
  }
}

I think where I’m hitting problems most is trying to figure out how exactly the actual instantiation of “a HexMap with a RandomHexMapStore mixed in” should take place, or in other words where the definition of the specific component assembly I’m creating should appear.  In Spring this would be an object graph defined either in a (probably big, crazy, and unwieldy) XML file or via annotations on various class declarations.

What I’ve been trying for starters is just to define a factory method which returns a new random map:

object RandomHexMapStore {
   def create(height: Int, width: Int): HexMap = {
     new HexMap(height, width) with RandomHexMapStore
  }
}

This is working OK for now, and it makes sense to me that different implementations of HexMapStore might have different constructor parameters, so I’m not too bothered by factory methods in general. I’m a little worried by how this approach might or might not scale to much larger class / object graphs, though.

Moreover, so far I’ve been glossing over the most serious immediate problem I have with this: the implementation of the RandomHexMapStore.createRandomMap() method. This method is meant to construct a map composed of randomly selected color elements. The problem is that, being a trait which is mixed in to HexMap, is has no access to HexMap’s height and width class parameters. What I have at the moment is this:

  private def createRandomMap(): Map[Address, ColorData] = {
    // Well, this isn't ideal
    val pairs = for (i <- 1 to 6; j <- 1 to 6) 
                yield Address(i,j) -> 
                      new ColorData(Address(i,j), randomColor())
    pairs toMap
  }

I’m a little baffled by how to get access to class parameters from a trait which is mixed in to that class. When I think about it, I can’t really see a good reason for Scala to allow it, since, after all, RandomHexMapStore could be mixed into any class, not just a descendant of HexMap. This suggests to me that I am probably not using the proper language mechanism for what I’m trying to do. I will have to do some thinking on this, and possibly call on Stack Overflow for help.

The jadening

Bolting Scalatra on to the existing hexmap project turned out to be fairly easy, though I had the advantage of having an existing minimal project already (the nascent random-album-cover project).  My idea for this project is to have nearly all the server transactions handled through Ajax rather than form posts and server-side templating, but while I was getting the directory structure up and running I took the opportunity to translate the existing HTML that I developed for the hexmap into Jade.

My initial impulse, actually, was to use Mustache, and avoid rewriting the HTML altogether.  However, I found the layout documentation for scalate Mustache to be basically incomprehensible, and if I’m understanding it correctly, it requires you to insert extra stuff into your layout file and still not remove anything from your content file, which doesn’t exactly seem like it’s heading in the right direction as far as templating system design.  Besides, using Jade lets me pretend that I live in a universe where SGML-derived syntaxes never became something that almost every working programmer would have to deal with almost every day.

The downside of this is that I’m no longer able to monkey with the client-side code without a running jetty instance, but I think that should be OK for the near future.  The upside is that the code for index.html has shrank down to a svelte 36 lines.

At any rate, I’ve got the client code retrieving and painting a map from the server now.  My server-side map database currently looks like this:

  get("/map/new.json") {
    contentType = "application/json"
    """{ "map" : [["blue", "brown", "yellow"],
                  ["lightgreen", "yellow", "blue"],
                  ["grey", "grey", "darkgreen"]] }"""
  }

It’s a start. I’ve also pulled in the Lift-JSON libraries, which look to be useful. The next step is to implement a few different map stores, hook them up to the client, and test the output. After that, I need to figure out a way to populate actually interesting map data in a persistent store (presumably Mongo). The idea which keeps nagging at the back of my mind is that the existing code could probably be used as the start of a dynamic map editor, but I’m not positive I want to head down that route.

Ars hexica

After spending a while uselessly flailing around trying to get the Gimp to do what I wanted it to do, I wised up and checked out some directions for tile creation on the Wesnoth site, which pointed me in the direction of the open-source SVG editor Inkscape. Inkscape, among other nice features, has a polygon tool which is able to make regular hexagons and the like. It will also export selected objects as PNG files, so with minimal effort I’ve been able to replace the tiles I swiped from Wesnoth with new, boring ones of my own devising. Among other improvements, I’ve got lines around the hexes now, and the hexagons themselves are regular. Encouragingly, I didn’t need to change the javascript at all to deal with the new sizes, since it works by inspecting the img sizes from their attributes directly and basing its math on that.

Along those same lines, I’ve been pretty pleased with how easy it is to separate presentation logic from presentation markup in jQuery.  Apart from switching image sizes, I can see that it would be fairly easy to set up the function which generates random tiles, randomTile(), to dynamically query the DOM tree, find all of the possible tiles, and then pick one at random (currently it uses a static list of possible tile names).  Together with attaching arbitrary custom data to each possible tile, this seems like a promising approach to some sort of game, with a classic game engine / game content separation.  However, Barbarian Prince is not that game, being based on a static game map, and part of the point of this exercise has been to learn Scala, so it’s back to the server side after this.

After finding Inkscape, I spent a while  messing around with different sizes for the hexes in the hexmap.  For a while I was considering using either SVG or HTML5 canvas elements or some such to represent the map, with the idea that it would allow a more easy way to zoom in and out from the map.  I feel like both of those areas represent rather large and interesting rabbit holes, though, and I’ve only just emerged from the jQuery rabbit hole I was in.  Moreover, having distinct tiles seems like a good match for the game as it was written.

The next steps are to head back out to terra incognita and add this stuff to the project:

  • A more beefed-up definition of the hexmap definition (as a JSON, uh, schema).
  • A persistent store on the Scala side which is capable of storing and retrieving this definition (most likely via mongodb, since I’m familiar with it and it has a well-regarded Scala interface).
  • Simple REST service definitions on the Scala side, and, oh yeah, a web server framework to serve them up, most likely with Scalatra.
  • An Ajax call from index.html to get the persisted hexmap from the Scala server and display it.

I will note in passing that it has occurred to me that Barbarian Prince as she is spoke could probably be easily implemented purely through jQuery and HTML5 client-side storage (which I guess seems to mean indexedDB as of February 2012), keeping all game logic and map creation on the client side.  This would certainly reduce network latency for players, as well as the need for highly-skilled developers on server side.  This is an approach that somebody who isn’t trying to get experience in programming Scala should probably pursue.

Javascript hexmap display

hexagon map

After a good bit of head-scratching I’ve managed to make some progress on what I assumed was going to be one of the more difficult aspects of the hex-map project: actually displaying the hexes in a browser.  This also turned out to be a good opportunity to finally dig into jQuery a little more deeply, too.  I’ve come up with a rough idea of how to proceed from here, too; I’ll have the page make Ajax calls out to Scala to retrieve map details in JSON and it should be pretty easy to dynamically construct the hex grids from there.

Github, probably wisely, doesn’t display checked-in HTML directly in the browser, but I’ll attach a screenshot here; interested parties can check out the code on github under src/main/webapp.  Currently the page generates a new random map on every page refresh, with each map being a mixture of roughly 2/3 desert tiles and 1/3 ocean tiles.  The data structure is a simple 2-dimensional array:

 var map = [["desert", "ocean", "desert"],
            ["desert", "ocean", "desert"],
            ["desert", "desert", "ocean"]]

Obviously for a full game implementation the elements would be complex JSON structures, not strings, but this suffices for now.  To tile the hexes together, I’m simply laying them on top of one another via CSS absolute positioning; each image is a rectangle (actually, a square) with the diagonal edges cut out of the sides.  I was a little worried this would make it cumbersome to attach jQuery event handlers to the right places, but I currently have a handler that displays the (x,y) coordinates of a hex when a user mouses over one and it seems very usable, if not perfect around the edges of hexes.

The code I’m using to position the tiles looks roughly like this (note: some cleanup is still pending in the actual code; what follows is the gist but see the code itself for details).  Here tile is a string from the previous array, and x and y are row / column numbers.

function placeTile(tile, x, y) {
  var tile$ = $("." + tile, "#templates").children().clone();

  tile$.hexMapPosition(x, y).appendTo($('#hexmap'));
}

This code clones images based on the tile name from the map data structure. The images themselves are stored in a hidden div:

<div id="templates" class="hidden">
  <div class="tiles desert">
    <img src="images/tiles/desert.png" width="72" height="72"/>
  </div>
  <div class="tiles ocean">
    <img src="images/tiles/ocean.png" width="72" height="72"/>
  </div>
</div>

It then positions them via a jQuery extension, hexMapPosition(), which examines the image’s height and width and then calculates an absolute position for the top left pixel.

  (function($) {
    $.fn.hexMapPosition = function(row, column) {
      var tile_width = this.attr("width");
      var tile_height = this.attr("height");

      // Haven't done the math to check these but they work
      var y_offset = tile_height / 2;
      var x_offset = tile_width / 4;

      var xpos = row * (tile_width - x_offset));
      var ypos = column * tile_height);

      if (row % 2 == 0) {
        ypos -= y_offset;    // Every other row, offset down
      }

      return this.css({"position": "absolute", "top": ypos, "left": xpos});
    }
  })(jQuery);

This isn’t perfect, but it’s a good place to start. Some problems I’ve got with it:

  • The hexagon pngs are ones I’ve borrowed from the Battle for Wesnoth project, and are a bit irregular (literally – the top edges are shorter than those on the sides). This does seem to make the math easy, though. I should note here that the PNGs are published under the GPLv2, though to be honest, I have no clue how the GPLv2 could possibly apply to images.
  • I’m a little worried that overlaying further PNGs on top of these ones (for map highlighting, roads, player markers, etc) will interfere with the mouseover events, but I’ll need to experiment.
  • I had a lot of trouble trying to get little borders to appear between hexes by monkeying with the positioning values above.

Edit: having recently discovered jsfiddle, I uploaded a fiddle of this there. I’ve also manage to clean up the code so that it is currently in much better shape on jsfiddle than it is in github, but the github version will be changing and it will be nice to keep a clean version of the basic idea around.

An interlude

Over the holidays I became distracted by another project; I stumbled across this post on MetaFilter and started to wonder about how best to model and implement a hexagonal map grid in software.  I’ve spent a bit of time banging together the bones of an implementation in Scala, which the curious can find on github at my account.  Here are some notes from the experience:

  • The Scala API documentation leaves something to be desired, especially when approaching it as a beginner.  In particular, it could use a good deal more examples, as well as explanatory text containing links to relevant classes.  In fairness, this is something the Java API docs also suffer from, and it might be that my own inexperience is at the root of the problem.
  • The Scala IRC channel was extremely helpful; some of its inhabitants gave me advice on some syntax problems I was having (it would have been very difficult to google these) and advice on how to better structure my code.
  • Somebody on the IRC channel described Scala’s Enumerations as a failed experiment, a description which did not surprise me after I tried a use one as a key to a Map.  It seems that case classes (or more precisely, case objects) are probably the way to go for these, in the absence of a Lisp / Ruby – like “symbol” class.  There are more details about this at this blog post.  I may be missing something, but the Scala enumeration class seems less type-safe than the Java implementation does, which is not a common occurrence.

I will probably mess with the hex map stuff a bit more before going back to the random-album-cover project, as it will be a good opportunity to mess around with type parameters and storage in Scala, as well as letting me dust off some graph traversal algorithms.

The Cake walk

I come from a very Spring-heavy background in Java.  Spring is a bit of a loose, baggy monster, containing probably hundreds of features which aren’t all terribly well-connected to one another, but one thing that became second nature to me in Spring was the dependency-injection and IoC features.  Structuring software into composable components makes sense to me for scalability and ease of testing.

There are a few logical bits in random-album-cover that are clear candidates for components.  In particular,  the three distinct bits of information we’re getting from the web should probably each have a testing implementation and a live one (one which actually connects to the web and scrapes a page).  My Java instincts would probably structure the code something like the following:

interface Cover { ... }
class CoverImpl implements Cover { ... }

interface QuoteService {
    String getQuote();
}
class TestingQuoteServiceImpl implements QuoteService {
    String getQuote() { return "testing"; }
}
class LiveQuoteServiceImpl implements QuoteService {
    String getQuote() {
        // Fire up httpClient, connect to quote page, scrape for quote
        return result;
    }
}

interface CoverFactory {
    Cover generateNewCover();
}
class CoverFactoryImpl {
    QuoteService quoteService;
    Cover generateNewCover() {
        String quote = quoteService.getQuote();
        return new CoverImpl(quote);
    }
    void setImageService(QuoteService imageService) { ... }
}

Not shown: some Spring configuration that would wire up one of the two quote factory implementations into a CoverFactoryImpl instance.

None of this is rocket science. Translating it to idiomatic Scala is a bit trickier than it seemed at first. There are a few libraries which exist to do dependency injection in Scala, but there is also a method which relies on native library features, the Cake Pattern.  Adam Warski’s post from 2010 is a good summary of the idea, with code examples.

Digging a little more deeply into it, though, I found some discussion of the Cake Pattern which gave me pause.  In particular, the discussion on this post from Adam Warski, along with this post by Przemek Pokrywka and this one by Debasish Ghosh made me wonder if my understanding of what exactly the pattern does and how to implement it was not quite up to speed.

This had the salutary effect of driving me back to my primary sources (the Odersky et al “staircase book” and to a lesser extent, the O’Reilly book) for a refresher on self type annotations.  I’m still not entirely sure I grasp what the ultimate purpose of self types are; I can see the pragmatic effect of requiring that a concrete class which mixes in one trait must also mix in the trait that is referred to as a self type, but I don’t exactly see how to generalize this to more than a one-to-one trait relationship.  In some of the larger Spring projects I have worked on, literally hundreds of services (Java singleton instances) were composed and wired together — in the end there was an object graph.  If traits can only declare one self type, though, I don’t quite see how you would use this mechanism for anything other than an object list.  Clearly I’m missing something, but the staircase book is uncharacteristically terse on this point.

In any event, all was not lost, because chapter 29 of the staircase book essentially sets out to solve the exact problem I’d been working on: how best to structure and compose component-based software in Scala.  There seem to be a few ways of going about it, but for now I should have some simple examples to use as the basis for assembling my tiny services.  (It also opens up the possibility of comparing some of the more lightweight Scala DI frameworks down the road, which is something I’d probably enjoy.)

Follow

Get every new post delivered to your Inbox.