Precision in speech-based communications

29 July 2010 | 3:38 pm by codeboxer

Precision in speech-based communications

I will start with a quote, which is ostensibly a technical communication. Sure it is from a 'message board', which is more or less an informal medium, but that does not mean that universal rules of logic will not apply. Besides, it is a work message board (Campfire), and is used extensively as a measure of our internal communications. I think at the root of it that all communications should and for the most part will be judged mainly in terms of how effective they are, and to a smaller extent in terms of the economy of effort involved with understanding them. So here's the quote:

"the fix that fixes the workflow tests no longer applies, so 2 of the 3 will still be broken - FYI"

This is from a small team of developers working together on a single code base, with a set of automated tests that are maintained collectively. The expectations here are as stated above, namely that the message be effective and succinct. What Is Being Said?, as well as How long Does It Take Me To Understand It? should be the two questions in mind when assessing the inherent value of this message.

What Is Being Said?

In essence, we have a simple logical statement here - premise, conclusion. This is so, so that is so. Let's examine the first part, the premise.

the fix that fixes the workflow tests no longer applies

There are many potential meanings here, which one might call an ambiguous premise. First, the word 'fix' is used as both a subject and a verb, which is bad form. It would be better to replace one or the other with a valid synonym, just to avoid confusion. The 'fix that addresses the workflow tests', perhaps.
Next, we can see that 'the workflow tests' are referred to collectively, which is a mistake in specificity. The employee here knows very well that there are only 3 specific tests that are affected - the 3 that are mentioned in the conclusion - but they prefer to describe as little as possible, essentially missing two chances to actually specify them. Of course, brevity is king, but it would be as easy as saying the 'fix that addresses the drug_name workflow tests' which is only one extra word but helps us get much closer to a specific and limited subject from which to subsequently draw a conclusion. Finally, the last glaring problem here is that the phrase 'no longer applies' is badly worded because it implies another question, namely 'why does it no longer apply?'. It is also interesting that the employee goes to a certain length to be non-explicit - vagueness also at the expense of brevity. Did the tests break? Is it true that the 'fix' still 'fixes' the tests, if it 'no longer applies'? The premise itself borders on the nonsensical. Better to say 'the drug_name workflow tests are broken', or maybe 'the drug_name workflow tests are no longer needed', or 'the drug_name workflow tests need to be refactored'. All 3 of those different scenarios are perhaps referenced by this statement but we don't know which.

so 2 of the 3 will still be broken - FYI
Stemming from an ambiguous premise, this is hard to parse, but we can see a few simple problems with the form again.

First, '2 of the 3' - which three? Using 'the' here implies that we know which 3 to which the speaker refers, but this is the first time we hear of that number. So, in essence the reader is forced to conclude that the number 3 refers to the collective statement about workflow tests in the premise, but that is by no means explicit and fails one or both our expectations, depending on how generous you are - either it communicates ineffectively AND takes more time than necessary to understand, or it just takes more time than necessary to understand.

And yet again, the phraseology 'will still be broken' implies that we know already that they are broken and are being informed simply that they will remain so, another mistake in the reference chain, if you will. We were never actually told that anything was already broken - if you remember, we were told just that 'the fix...no longer applies', so this conclusion leaves us, among other things, wondering if we were supposed to have had some information in the premise that was never forthcoming.

So, to conclude, we have no conclusion. We are left with more questions than answers. As I just mentioned, we are not sure if we missed something in the premise; we don't know why whatever just happened only applies to '2 of the 3'; and we have absolutely no expectation for the future which is usually what statements like these are used for. We don't know if this is a surprise, if someone should be working on it or perhaps already is, if this is a temporary state that will resolve itself somehow; so the usage of FYI is both unfortunate and supremely ironic, because of all the thing we have here, information is not one of them.

So please - be specific. Every time someone misses the opportunity to communicate effectively the whole world gets a little bit dumber.

you need this to run rails on ubuntu

22 July 2010 | 10:29 pm by codeboxer
sudo apt-get install libopenssl-ruby

in order to combat this error:

no such file to load -- openssl

be forewarned.

the Law of Demeter

20 July 2010 | 12:15 pm by codeboxer

More formally, the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:

1. O itself
2. M's parameters
3. any objects created/instantiated within M
4. O's direct component objects
5. a global variable, accessible by O, in the scope of M

http://en.wikipedia.org/wiki/Law_of_Demeter

Silly Dev jokes

14 July 2010 | 4:22 pm by codeboxer

copied from: http://blogs.adobe.com/charles/2010/05/ill_trade_you_a_joke_for_a_book.h...

  • By Jeremy - 6:01 PM on May 20, 2010  

    There are only 10 types of people in the world: those who understand binary and those who don’t.

  • By Richie - 12:34 AM on May 24, 2010  

    A programmers high-school girlfriend is like the square root of -2…irrational and imaginary.

  • By gem_reader - 4:29 PM on May 26, 2010  

    “Knock, knock.”
    “Who’s there?”
    very long pause…..
    “Java.”

  • By Borek Bernard - 2:32 AM on May 27, 2010  

    Rather a geek joke but a good one:
    Schrodinger’s cat walks into a bar…and doesn’t

  • By codeabonde - 12:27 PM on June 1, 2010  

    In C we had to code our own bugs. In C++ we can inherit them.

  • By Yazbar - 1:11 PM on June 3, 2010  

    Q: How many programmers does it take to change a light bulb?
    A: None. That’s a hardware problem.

  • By Hoover - 1:20 PM on June 4, 2010  

    My other car is a CDR

  • By mastersson - 9:12 AM on June 8, 2010  

    Q: How many IBM Processors does it take to execute a job?
    A: Four. Three to hold it down, and one to rip it’s head off.

  • By Penny - 8:15 PM on July 12, 2010  

    Why do programmers always mix up Halloween and Christmas?
    Because Oct 31 equals Dec 25.

  • By James hall - 10:23 PM on July 14, 2010  

    a sql query walks into a bar and sees two tables. He walks up and says “can i join you?”

fun with closures

8 July 2010 | 5:20 pm by codeboxer

I got burned by not being able to answer the question -'what are closures?" with much of anything. It was pretty embarrassing, seeing as I use them all day. :)

I had a decent enough explanation about passing code blocks around, but what I forgot to mention was the 'yield' keyword (which is a bit like talking about soup and forgetting to mention that you have to add water).

Also, I started trying to write up an example (like I have seen Brian Guthrie do so many times) and couldn't come up with a good one fast enough.

Anyway, I am decidedly a pragmatist and I don't get as academic as some of my more CS-based brethren, but I decided then to starting boning up on good examples of what closure is so I can do myself justice next time someone asks me that question.

so I found this (by some dude named Paul):


# CLOSURES IN RUBY     Paul Cantrell    http://innig.net
# Email: username "cantrell", domain name "pobox.com"

# I recommend executing this file, then reading it alongside its output.
#
# Alteratively, you can give yourself a sort of Ruby test by deleting all the comments,
# then trying to guess the output of the code!

# A closure is a block of code which meets three criteria:
# 
#     * It can be passed around as a value and
# 
#     * executed on demand by anyone who has that value, at which time
# 
#     * it can refer to variables from the context in which it was created
#       (i.e. it is closed with respect to variable access, in the
#       mathematical sense of the word "closed").
#
# (The word "closure" actually has an imprecise meaning, and some people don't
# think that criterion #1 is part of the definition. I think it is.)
# 
# Closures are a mainstay of functional languages, but are present in many other
# languages as well (e.g. Java's anonymous inner classes). You can do cool stuff
# with them: they allow deferred execution, and some elegant tricks of style.
# 
# Ruby is based on the "principle of least surprise," but I had a really nasty
# surprise in my learning process. When I understood what methods like "each"
# were doing, I thought, "Aha! Ruby has closures!" But then I found out that a
# function can't accept multiple blocks -- violating the principle that closures
# can be passed around freely as values.
# 
# This document details what I learned in my quest to figure out what the deal is.

def example(num)
    puts
    puts "------ Example #{num} ------"
end

# ---------------------------- Section 1: Blocks ----------------------------

# Blocks are like closures, because they can refer to variables from their defining context:

example 1

def thrice
    yield
    yield
    yield
end

x = 5
puts "value of x before: #{x}"
thrice { x += 1 }
puts "value of x after: #{x}"

# A block refers to variables in the context it was defined, not the context in which it is called:

example 2

def thrice_with_local_x
    x = 100
    yield
    yield
    yield
    puts "value of x at end of thrice_with_local_x: #{x}"
end

x = 5
thrice_with_local_x { x += 1 }
puts "value of outer x after: #{x}"

# A block only refers to *existing* variables in the outer context; if they don't exist in the outer, a
# block won't create them there:

example 3

thrice do # note that {...} and do...end are completely equivalent
    y = 10
    puts "Is y defined inside the block where it is first set?"
    puts "Yes." if defined? y
end
puts "Is y defined in the outer context after being set in the block?"
puts "No!" unless defined? y

# OK, so blocks seem to be like closures: they are closed with respect to variables defined in the context
# where they were created, regardless of the context in which they're called.
# 
# But they're not quite closures as we've been using them, because we have no way to pass them around:
# "yield" can *only* refer to the block passed to the method it's in.
#
# We can pass a block on down the chain, however, using &:

example 4

def six_times(&block)
    thrice(&block)
    thrice(&block)
end

x = 4
six_times { x += 10 }
puts "value of x after: #{x}"

# So do we have closures? Not quite! We can't hold on to a &block and call it later at an arbitrary
# time; it doesn't work. This, for example, will not compile:
#
# def save_block_for_later(&block)
#     saved = █
# end
#
# But we *can* pass it around if we use drop the &, and use block.call(...) instead of yield:

example 5

def save_for_later(&b)
    @saved = b  # Note: no ampersand! This turns a block into a closure of sorts.
end

save_for_later { puts "Hello!" }
puts "Deferred execution of a block:"
@saved.call
@saved.call

# But wait! We can't pass multiple blocks to a function! As it turns out, there can be only zero
# or one &block_params to a function, and the ¶m *must* be the last in the list.
#
# None of these will compile:
#
#    def f(&block1, &block2) ...
#    def f(&block1, arg_after_block) ...
#    f { puts "block1" } { puts "block2" }
#
# What the heck?
#
# I claim this single-block limitation violates the "principle of least surprise." The reasons for
# it have to do with ease of C implementation, not semantics.
#
# So: are we screwed for ever doing anything robust and interesting with closures?


# ---------------------------- Section 2: Closure-Like Ruby Constructs ----------------------------

# Actually, no. When we pass a block ¶m, then refer to that param without the ampersand, that
# is secretly a synonym for Proc.new(¶m):

example 6

def save_for_later(&b)
    @saved = Proc.new(&b) # same as: @saved = b
end

save_for_later { puts "Hello again!" }
puts "Deferred execution of a Proc works just the same with Proc.new:"
@saved.call

# We can define a Proc on the spot, no need for the ¶m:

example 7

@saved_proc_new = Proc.new { puts "I'm declared on the spot with Proc.new." }
puts "Deferred execution of a Proc works just the same with ad-hoc Proc.new:"
@saved_proc_new.call

# Behold! A true closure!
#
# But wait, there's more.... Ruby has a whole bunch of things that seem to behave like closures,
# and can be called with .call:

example 8

@saved_proc_new = Proc.new { puts "I'm declared with Proc.new." }
@saved_proc = proc { puts "I'm declared with proc." }
@saved_lambda = lambda { puts "I'm declared with lambda." }
def some_method 
    puts "I'm declared as a method."
end
@method_as_closure = method(:some_method)

puts "Here are four superficially identical forms of deferred execution:"
@saved_proc_new.call
@saved_proc.call
@saved_lambda.call
@method_as_closure.call

# So in fact, there are no less than seven -- count 'em, SEVEN -- different closure-like constructs in Ruby:
#
#      1. block (implicitly passed, called with yield)
#      2. block (&b  =>  f(&b)  =>  yield)  
#      3. block (&b  =>  b.call)    
#      4. Proc.new  
#      5. proc  
#      6. lambda    
#      7. method
#
# Though they all look different, some of these are secretly identical, as we'll see shortly.
#
# We already know that (1) and (2) are not really closures -- and they are, in fact, exactly the same thing.
# Numbers 3-7 all seem to be identical. Are they just different syntaxes for identical semantics?

# ---------------------------- Section 3: Closures and Control Flow ----------------------------

# No, they aren't! One of the distinguishing features has to do with what "return" does.
#
# Consider first this example of several different closure-like things *without* a return statement.
# They all behave identically:

example 9

def f(closure)
    puts
    puts "About to call closure"
    result = closure.call
    puts "Closure returned: #{result}"
    "Value from f"
end

puts "f returned: " + f(Proc.new { "Value from Proc.new" })
puts "f returned: " + f(proc { "Value from proc" })
puts "f returned: " + f(lambda { "Value from lambda" })
def another_method
    "Value from method"
end
puts "f returned: " + f(method(:another_method))

# But put in a "return," and all hell breaks loose!

example 10

begin
    f(Proc.new { return "Value from Proc.new" })
rescue Exception => e
    puts "Failed with #{e.class}: #{e}"
end

# The call fails because that "return" needs to be inside a function, and a Proc isn't really
# quite a full-fledged function:

example 11

def g
    result = f(Proc.new { return "Value from Proc.new" })
    puts "f returned: " + result #never executed
    "Value from g"               #never executed
end

puts "g returned: #{g}"

# Note that the return inside the "Proc.new" didn't just return from the Proc -- it returned
# all the way out of g, bypassing not only the rest of g but the rest of f as well! It worked
# almost like an exception.
#
# This means that it's not possible to call a Proc containing a "return" when the creating
# context no longer exists:

example 12

def make_proc_new
    begin
        Proc.new { return "Value from Proc.new" } # this "return" will return from make_proc_new
    ensure
        puts "make_proc_new exited"
    end
end

begin
    puts make_proc_new.call
rescue Exception => e
    puts "Failed with #{e.class}: #{e}"
end

# (Note that this makes it unsafe to pass Procs across threads.)

# A Proc.new, then, is not quite truly closed: it depends in the creating context still existing,
# because the "return" is tied to that context.
#
# Not so for lambda:

example 13

def g
    result = f(lambda { return "Value from lambda" })
    puts "f returned: " + result
    "Value from g"
end

puts "g returned: #{g}"

# And yes, you can call a lambda even when the creating context is gone:

example 14

def make_lambda
    begin
        lambda { return "Value from lambda" }
    ensure
        puts "make_lambda exited"
    end
end

puts make_lambda.call

# Inside a lambda, a return statement only returns from the lambda, and flow continues normally.
# So a lambda is like a function unto itself, whereas a Proc remains dependent on the control
# flow of its caller.
#
# A lambda, therefore, is Ruby's true closure.
#
# As it turns out, "proc" is a synonym for either "Proc.new" or "lambda."
# Anybody want to guess which one? (Hint: "Proc" in lowercase is "proc.")

example 15

def g
    result = f(proc { return "Value from proc" })
    puts "f returned: " + result
    "Value from g"
end

puts "g returned: #{g}"

# Hah. Fooled you.
#
# The answer: Ruby changed its mind. If you're using Ruby 1.8, it's a synonym for "lambda."
# That's surprising (and also ridiculous); somebody figured this out, so in 1.9, it's a synonym for
# Proc.new. Go figure.

# I'll spare you the rest of the experiments, and give you the behavior of all 7 cases:
#
# "return" returns from caller:
#      1. block (called with yield)
#      2. block (&b  =>  f(&b)  =>  yield)  
#      3. block (&b  =>  b.call)    
#      4. Proc.new
#      5. proc in 1.9
#
# "return" only returns from closure:
#      5. proc in 1.8
#      6. lambda    
#      7. method

# ---------------------------- Section 4: Closures and Arity ----------------------------

# The other major distinguishing of different kinds of Ruby closures is how they handle mismatched
# arity -- in other words, the wrong number of arguments.
#
# In addition to "call," every closure has an "arity" method which returns the number of expected
# arguments:

example 16

puts "One-arg lambda:"
puts (lambda {|x|}.arity)
puts "Three-arg lambda:"
puts (lambda {|x,y,z|}.arity)

# ...well, sort of:

puts "No-args lambda: "
puts (lambda {}.arity) # This behavior is also subject to change in 1.9.
puts "Varargs lambda: "
puts (lambda {|*args|}.arity)

# Watch what happens when we call these with the wrong number of arguments:

example 17

def call_with_too_many_args(closure)
    begin
        puts "closure arity: #{closure.arity}"
        closure.call(1,2,3,4,5,6)
        puts "Too many args worked"
    rescue Exception => e
        puts "Too many args threw exception #{e.class}: #{e}"
    end
end

def two_arg_method(x,y)
end

puts; puts "Proc.new:"; call_with_too_many_args(Proc.new {|x,y|})
puts; puts "proc:"    ; call_with_too_many_args(proc {|x,y|})
puts; puts "lambda:"  ; call_with_too_many_args(lambda {|x,y|})
puts; puts "Method:"  ; call_with_too_many_args(method(:two_arg_method))

def call_with_too_few_args(closure)
    begin
        puts "closure arity: #{closure.arity}"
        closure.call()
        puts "Too few args worked"
    rescue Exception => e
        puts "Too few args threw exception #{e.class}: #{e}"
    end
end

puts; puts "Proc.new:"; call_with_too_few_args(Proc.new {|x,y|})
puts; puts "proc:"    ; call_with_too_few_args(proc {|x,y|})
puts; puts "lambda:"  ; call_with_too_few_args(lambda {|x,y|})
puts; puts "Method:"  ; call_with_too_few_args(method(:two_arg_method))

# Yet oddly, the behavior for one-argument closures is different....

example 18

def one_arg_method(x)
end

puts; puts "Proc.new:"; call_with_too_many_args(Proc.new {|x|})
puts; puts "proc:"    ; call_with_too_many_args(proc {|x|})
puts; puts "lambda:"  ; call_with_too_many_args(lambda {|x|})
puts; puts "Method:"  ; call_with_too_many_args(method(:one_arg_method))
puts; puts "Proc.new:"; call_with_too_few_args(Proc.new {|x|})
puts; puts "proc:"    ; call_with_too_few_args(proc {|x|})
puts; puts "lambda:"  ; call_with_too_few_args(lambda {|x|})
puts; puts "Method:"  ; call_with_too_few_args(method(:one_arg_method))

# Yet when there are no args...

example 19

def no_arg_method
end

puts; puts "Proc.new:"; call_with_too_many_args(Proc.new {||})
puts; puts "proc:"    ; call_with_too_many_args(proc {||})
puts; puts "lambda:"  ; call_with_too_many_args(lambda {||})
puts; puts "Method:"  ; call_with_too_many_args(method(:no_arg_method))

# For no good reason that I can see, Proc.new, proc and lambda treat a single argument as a special
# case; only a method enforces arity in all cases. Principle of least surprise my ass.



# ---------------------------- Section 5: Rant ----------------------------
#
# This is quite a dizzing array of syntactic options, with subtle semantics differences that are not
# at all obvious, and riddled with minor special cases. It's like a big bear trap from programmers who
# expect the language to just work.
#
# Why are things this way? Because Ruby is:
#
#   (1) designed by implementation, and
#   (2) defined by implementation.
#
# The language grows because the Ruby team tacks on cool ideas, without maintaining a real spec apart
# from CRuby. A spec would make clear the logical structure of the language, and thus help highlight
# inconsistencies like the ones we've just seen. Instead, these inconsinstencies creep into the language,
# confuse the crap out of poor souls like me who are trying to learn it, and then get submitted as bug
# reports. Something as fundamental as the semantics of proc should not get so screwed up that they have
# to backtrack between releases, for heaven's sake! Yes, I know, language design is hard -- but something
# like this proc/lambda issue or the arity problem wasn't so hard to get right the first time.
# Yammer yammer.


# ---------------------------- Section 6: Summary ----------------------------
#
# So, what's the final verdict on those 7 closure-like entities?          
#
#                                                     "return" returns from closure
#                                    True closure?    or declaring context...?         Arity check?
#                                    ---------------  -----------------------------    -------------------
# 1. block (called with yield)       N                declaring                        no
# 2. block (&b => f(&b) => yield)    N                declaring                        no
# 3. block (&b => b.call)            Y except return  declaring                        warn on too few
# 4. Proc.new                        Y except return  declaring                        warn on too few
# 5. proc                                    <<< alias for lambda in 1.8, Proc.new in 1.9 >>>
# 6. lambda                          Y                closure                          yes, except arity 1
# 7. method                          Y                closure                          yes
#
# The things within each of these groups are all semantically identical -- that is, they're different
# syntaxes for the same thing:
#   
#      1. block (called with yield)
#      2. block (&b  =>  f(&b)  =>  yield)  
#      -------
#      3. block (&b  =>  b.call)
#      4. Proc.new  
#      5. proc in 1.9
#      -------
#      5. proc in 1.8
#      6. lambda    
#      -------
#      7. method (may be identical to lambda with changes to arity checking in 1.9)
#
# Or at least, this is how I *think* it is, based on experiment. There's no authoritative answer other
# than testing the CRuby implementation, because there's no real spec -- so there may be other differences
# I haven't discovered.
#
# The final verdict: Ruby has four types of closures and near-closures, expressible in seven syntactic
# variants. Not pretty. But you sure sure do cool stuff with them! That's up next....
#
# This concludes the "Ruby sucks" portion of our broadcast; from here on, it will be the "Ruby is
# awesome" portion.


# ---------------------------- Section 7: Doing Something Cool with Closures ----------------------------

# Let's make a data structure containing all of the Fibonacci numbers. Yes, I said *all* of them.
# How is this possible? We'll use closures to do lazy evaluation, so that the computer only calculates
# as much of the list as we ask for.

# To make this work, we're going to use Lisp-style lists: a list is a recursive data structure with
# two parts: "car," the next element of the list, and "cdr," the remainder of the list.
#
# For example, the list of the first three positive integers is [1,[2,[3]]]. Why? Because:
#
#   [1,[2,[3]]]     <--- car=1, cdr=[2,[3]]
#      [2,[3]]      <--- car=2, cdr=[3]
#         [3]       <--- car=3, cdr=nil
#
# Here's a class for traversing such lists:

example 20

class LispyEnumerable
    include Enumerable
    
    def initialize(tree)
        @tree = tree
    end
    
    def each
        while @tree
            car,cdr = @tree
            yield car
            @tree = cdr
        end
    end
end

list = [1,[2,[3]]]
LispyEnumerable.new(list).each do |x|
    puts x
end

# So how to make an infinite list? Instead of making each node in the list a fully built
# data structure, we'll make it a closure -- and then we won't call that closure
# until we actually need the value. This applies recursively: the top of the tree is a closure,
# and its cdr is a closure, and the cdr's cdr is a closure....

example 21

class LazyLispyEnumerable
    include Enumerable
    
    def initialize(tree)
        @tree = tree
    end
    
    def each
        while @tree
            car,cdr = @tree.call # <--- @tree is a closure
            yield car
            @tree = cdr
        end
    end
end

list = lambda{[1, lambda {[2, lambda {[3]}]}]} # same as above, except we wrap each level in a lambda
LazyLispyEnumerable.new(list).each do |x|
    puts x
end

example 22

# Let's see when each of those blocks gets called:
list = lambda do
    puts "first lambda called"
    [1, lambda do
        puts "second lambda called"
        [2, lambda do
            puts "third lambda called"
            [3]
        end]
    end]
end

puts "List created; about to iterate:"
LazyLispyEnumerable.new(list).each do |x|
    puts x
end


# Now, because the lambda defers evaluation, we can make an infinite list:

example 23

def fibo(a,b)
    lambda { [a, fibo(b,a+b)] } # <---- this would go into infinite recursion if it weren't in a lambda
end

LazyLispyEnumerable.new(fibo(1,1)).each do |x|
    puts x
    break if x > 100 # we don't actually want to print all of the Fibonaccis!
end

# This kind of deferred execution is called "lazy evaluation" -- as opposed to the "eager
# evaluation" we're used to, where we evaluate an expression before passing its value on.
# (Most languages, including Ruby, use eager evaluation, but there are languages (like Haskell)
# which use lazy evaluation for everything, by default! Not always performant, but ever so very cool.)
#
# This way of implementing lazy evaluation is terribly clunky! We had to write a separate
# LazyLispyEnumerable that *knows* we're passing it a special lazy data structure. How unsatisfying!
# Wouldn't it be nice of the lazy evaluation were invisible to callers of the lazy object?
#
# As it turns out, we can do this. We'll define a class called "Lazy," which takes a block, turns it
# into a closure, and holds onto it without immediately calling it. The first time somebody calls a
# method, we evaluate the closure and then forward the method call on to the closure's result.

class Lazy
  def initialize(&generator)
    @generator = generator
  end
   
  def method_missing(method, *args, &block)
    evaluate.send(method, *args, &block)
  end
  
  def evaluate
      @value = @generator.call unless @value
      @value
  end
end

def lazy(&b)
    Lazy.new &b
end

# This basically allows us to say:
#
#   lazy {value}
# 
# ...and get an object that *looks* exactly like value -- except that value won't be created until the
# first method call that touches it. It creates a transparent lazy proxy object. Observe:

example 24

x = lazy do
    puts "<<< Evaluating lazy value >>>"
    "lazy value"
end

puts "x has now been assigned"
puts "About to call one of x's methods:"
puts "x.size: #{x.size}"          # <--- .size triggers lazy evaluation
puts "x.swapcase: #{x.swapcase}"

# So now, if we define fibo using lazy instead of lambda, it should magically work with our
# original LispyEnumerable -- which has no idea it's dealing with a lazy value! Right?

example 25

def fibo(a,b)
    lazy { [a, fibo(b,a+b)] }
end

LispyEnumerable.new(fibo(1,1)).each do |x|
    puts x
end

# Oops! That didn't work. What went wrong?
#
# The failure started in this line of LispyEnumerable (though Ruby didn't report the error there):
#
#      car,cdr = @tree
#
# Let's zoom in on that result, and see what happened:

example 26

car,cdr = fibo(1,1)
puts "car=#{car}  cdr=#{cdr}"

# Here's the problem. When we do this:
#
#   x,y = z
#
# ...Ruby calls z.respond_to?(to_a) to see if z is an array. If it is, it will do the multiple
# assignment; if not, it will just assign x=z and set y=nil.
#
# We want our Lazy to forward the respond_to? call to our fibo list. But it doesn't forward it,
# because we used the method_missing to do the proxying -- and every object implements respond_to?
# by default, so the method isn't missing! The respond_to? doesn't get forwarded; instead, out Lazy
# says "No, I don't respond to to_a; thanks for asking." The immediate solution is to forward
# respond_to? manually:

class Lazy
  def initialize(&generator)
    @generator = generator
  end
   
  def method_missing(method, *args, &block)
    evaluate.send(method, *args, &block)
  end
  
  def respond_to?(method)
      evaluate.respond_to?(method)
  end
  
  def evaluate
      @value = @generator.call unless @value
      @value
  end
end

# And *now* our original Lispy enum can work:

example 27

LispyEnumerable.new(fibo(1,1)).each do |x|
    puts x
    break if x > 200
end

# Of course, this only fixes the problem for respond_to?, and we have the same problem for every other
# method of Object. There is a more robust solution -- frightening, but it works -- which is to undefine
# all the methods of the Lazy when it's created, so that everything gets forwarded.
#
# And guess what? There's already a slick little gem that will do it:
#
#     http://moonbase.rydia.net/software/lazy.rb/
#
# Read the source. It's fascinating.

# ---------------------------- Section 8: Wrap-Up ----------------------------

# So sure, this was all entertaining -- but is it good for anything?
#
# Well, suppose you have an object which requires a network or database call to be created, or will
# use a lot of memory once it exists. And suppose that it may or may not be used, but you don't know
# at the time it's created whether it will be. Making it lazy will prevent it from consuming resources
# unless it needs to. Hibernate does this to prevent unnecessary DB queries, and it does it with more or
# less arbitrary Java objects (i.e. unlike ActiveRecord, it doesn't depend on a base class to do its
# lazy loading). Ruby can do the same thing, but with a lot less code!
#
# That's just an example. Use your imagination.
#
# If you're a functional langauge geek, and enjoyed seeing Ruby play with these ideas from Lisp and
# Haskell, you may enjoy this thread:
#
#     http://redhanded.hobix.com/inspect/curryingWithArity.html
#
# OK, I'll stop making your brain hurt now. Hope this has been a bit enlightening! The experience
# of working it out certainly was for me.
#
# Paul



 

ask me again, Aslan!

the ago function for writing on a whiteboard

1 July 2010 | 4:08 pm by codeboxer

So, if you are ever somewhere where they ask you to write code on the wall with dry-erase marker, then you are covered.

Me, I never realized how much I love using a keyboard and watching the letters I type appear on the screen. Writing by hand is for suckers and/or poets.


class Mod
  
  def self.ago(seconds)
    case true
    when seconds.to_i < 60
      s = seconds.to_i
      return "#{s} second#{s>1 ? "s" : ""} ago."
    when seconds.to_i < 3600
      m = seconds.to_i/60
      s = seconds.to_i%60
      return "#{m} minute#{m>1 ? "s" : ""}, #{s} second#{s>1 ? "s" : ""} ago."
    when seconds.to_i < (3600 * 24)
      h = seconds.to_i/3600
      m = (seconds.to_i/60)%60
      s = seconds.to_i%60
      return "#{h} hour#{h>1 ? "s" : ""}, #{m} minute#{m>1 ? "s" : ""}, #{s} second#{s>1 ? "s" : ""} ago."
    else
      d = seconds.to_i / (3600 * 24)
      h = (seconds.to_i/3600)%24
      m = (seconds.to_i/60)%60
      s = seconds.to_i%60
      return "#{d} day#{d>1 ? "s" : ""}, #{h} hour#{h>1 ? "s" : ""}, #{m} minute#{m>1 ? "s" : ""}, #{s} second#{s>1 ? "s" : ""} ago."
    end
  end
  
end

and the tests:


require 'test_helper'

class ModTest < ActiveSupport::TestCase
  test "ago function" do
    assert_equal "1 second ago.", Mod.ago(1)
    assert_equal "40 seconds ago.", Mod.ago(40)
    assert_equal "1 minute, 1 second ago.", Mod.ago(61)
    assert_equal "3 minutes, 1 second ago.", Mod.ago(181)
    assert_equal "2 minutes, 40 seconds ago.", Mod.ago(160)
    assert_equal "1 hour, 3 minutes, 1 second ago.", Mod.ago(3600 + 181)
    assert_equal "2 hours, 3 minutes, 2 seconds ago.", Mod.ago((3600 * 2)+ 182)
    assert_equal "1 day, 0 hour, 1 minute, 1 second ago.", Mod.ago((60*60*24) + 61)
    assert_equal "1 day, 3 hours, 1 minute, 1 second ago.", Mod.ago((60*60*24) + 3600 + 3600 + 3600 + 61)
    assert_equal "2 days, 3 hours, 0 minute, 6 seconds ago.", Mod.ago(((60*60*24)*2) + 3600 + 3600 + 3600 + 6)
  end
end



ruby to_boolean function

18 June 2010 | 3:49 pm by codeboxer

  def to_boolean(value, nil_value = false)
    value.downcase! if value.class == String
    case value
      when "no","false",false, "0", 0
        false
      when "yes","true",true, "1", 1
        true
      when nil
        nil_value 
      else
        !!value
      end
  end

paginator class

17 June 2010 | 9:58 am by codeboxer

lives in extensions/active_record

module Extensions
  module ActiveRecord
    # Understands how to generate counts and entries for the given scope, and offers some reasonable
    # pagination helper methods.
    class Paginator
      attr_reader :count, :entries, :page, :per_page

      def initialize(scope, opts={})
        @page     = opts[:page].try(:to_i)     || first_page
        @per_page = opts[:per_page].try(:to_i) || scope.proxy_scope.per_page

        @count = scope.count
        @entries = scope.paginate(:page => @page, :per_page => @per_page).all
      end

      def total_pages
        (count / per_page) + 1
      end
      alias :last_page :total_pages

      def has_next_page?
        page < total_pages
      end

      def has_prev_page?
        page > first_page
      end
      
      def first_page; 1; end
    end
    
    module Paginate
      def per_page
        @per_page || 10
      end
      
      def per_page=(per_page)
        @per_page = per_page
      end
      
      # Applies a pagination scope using the :page and :per_page options passed in. If none given,
      # defaults to page 1 and this model's per_page setting. Can be used independently of paginator.
      def paginate(opts={})
        page     = opts[:page].try(:to_i)     || 1
        per_page = opts[:per_page].try(:to_i) || per_page
        
        scoped :limit => per_page, :offset => (page - 1) * per_page
      end
      
      # Returns an instance of Extensions::ActiveRecord::Paginator applied to the current scope. Used
      # as the last call in a scope/association chain. There is no need to apply the +paginate+ scope if
      # you use this method.
      def paginator(opts={})
        Extensions::ActiveRecord::Paginator.new(self.scoped({}), opts.slice(:page, :per_page))
      end
    end
  end
end

ActiveRecord::Base.send :extend, Extensions::ActiveRecord::Paginate

push your git tags

14 June 2010 | 2:57 pm by codeboxer

like so:

  git push origin --tags

vmware 3 coupon code

21 May 2010 | 12:12 pm by codeboxer

This code should work for a few weeks yet. I just used it today, to bring the price down from $79.99 to $67.99.

Sweet!

hobbits in holes and chipmunks in a phonebooth

21 May 2010 | 11:01 am by codeboxer

When writing unit tests, for unit/quantity measurements it is important to do the right thing. The rule is that you must test against either hobbits or chipmunks, in their appropriate quantities.

Also, there is such a thing as shaving yaks. I do it all day. :)

http://en.wiktionary.org/wiki/yak_shaving

My Sites

from Last.fm

noonchild's Profile Page

Green Web Hosting! This site hosted by DreamHost.

My Site Links

Screenshots are featured above. If you visit gmgpulse, you may login as demo/demo.

Rockstar Television


© 2008-10 Krister Axel and codeboxer.com