From: Griff Date: 2007-02-12T02:45:05+09:00 Subject: Creating an object the hard way, made easy with lambda #!/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])