#!/usr/bin/env ruby
#$LastChangedRevision: 49 $

# The purpose of this sample is to demonstrate the application of
lambda
# expressions to create a rudimentary 'person object'.
#
# Its features Smalltalk style "message passing" and "variables are
private,
# methods are public" encapsulation.
#
# This sample is an approximation, and drastic simplification, of many
of the
# examples you find written in Scheme, as it does not provide an OO
system for
# use by the developer.
#
# This is OK, though, since the point of this example is only to
demonstrate
# one application of lambda expressions. You may use them to write
your own
# object system in Ruby, but then again why bother, Ruby has already
got
# what you need!

def get_abstract_person_object
    first_name = ""
	last_name = ""
	age = -1
	my_to_s = lambda {
        "FIRST NAME:'#{first_name}', LAST NAME:'#{last_name}',
AGE:'#{age}'\n"
	}
	new = lambda { |fn, ln, ag|
        first_name = fn
        last_name = ln
        age = ag
        nil
    }

	lambda { |msg|

		result = nil

		case msg[0]
            when :new
                new.call(msg[1], msg[2], msg[3])
			when :get_first_name
				result = first_name
			when :set_first_name
				result = first_name = msg[1]
			when :get_last_name
				result = last_name
			when :set_last_name
				result = last_name = msg[1]
			when :get_age
				result = lage
			when :set_age
				result = age = msg[1]
			when :to_s
				result = my_to_s.call
		end

		if result != nil
			result
		else
			"MESSAGE '#{msg[0]}' NOT UNDERSTOOD!"
		end
	}
end

kristy = get_abstract_person_object
puts "Create Kristy"
puts kristy.call([:to_s])
kristy.call([:set_first_name, "Kristy"])
kristy.call([:set_last_name, "T"])
kristy.call([:set_age, 27])
puts kristy.call([:to_s])

puts "Create Steve"
steve = get_abstract_person_object
steve.call([:set_first_name, "Steve"])
steve.call([:set_last_name, "M"])
steve.call([:set_age, 48])
puts steve.call([:to_s])

puts
puts "Are the two 'objects' really different entities? YES.\n"
puts kristy.call([:to_s])
puts steve.call([:to_s])

puts
puts "What happens when you send a message that the object does not
understand?"
puts kristy.call([:foo])

puts
puts "A \"constructor\" message"
dave = get_abstract_person_object
dave.call([:new, "David", "O", 28])
puts dave.call([:to_s])