marick edited this page Jan 13, 2012 · 2 revisions

As explained in the video, my thinking about classes and modules these days is that they're organization and documentation tools. I want to program using hashes instead of custom objects. But I also want to say things like "That hash there? It's "shaped" like a Zipper, so there are certain functions that you should know about if you want to work with it. You can find those functions in the ZipperShaped module."

A problem with that is that Ruby modules are all about providing constants and methods to the classes that include them. But I want real functions (lambdas), not methods.

The defn method within Stunted lets you add functions to modules in a way that mades them as usable as methods.

Consider this code:

module FunctionProvider
  extend Stunted::Defn
  defn :add, -> a, b { a + b }

defn defines a method that has no purpose other than to make a function available. Anything including FunctionProvider can use the add function as if it were defined locally. Here's a local definition:

add_local = -> a, b { a + b }
puts add_local.(1, 2)   #=> 3

Here's the same thing done via module inclusion:

include FunctionProvider
puts add.(1, 2) #=> 3

All the capturing-over-local-variables goodness that you expect from functions is available with defn-defined functions:

module FunctionProvider
  captured = 3
  defn :add_captured, -> a { a + captured }

puts add_captured.(1)   #=> 4

The captured variables don't have to be defined within the module, because you can invoke defn from outside the module:

some_local = 88
FunctionProvider.defn :captured_value, -> { some_local }

# FunctionProvider has already been included.
puts captured_value.()  # 88

# Captured variables can be changed, if you want to venture into 
# the wilds of mutable state:
some_local = 99
puts captured_value.()  # 99

I expect to use captured variables to implement ideas like "a part of this hash, named :data, contains a Timestamp. So give this whole hash timestamp-manipulation functions that know where the timestamp lives."