TMTOWTDI – OOP Class

In Functional Programming paradigm, we could simulate what is called a class in OO terminology. We are not here to simulate the whole OO paradigm in FP paradigm because it would be a waste of time.

A class (in fact, an object) can maintain its state through its attributes and it can expose its state through its methods (or accessors). That being said, can it be done in Perl without the bless operator? Yes, it can be done. We just need a different ingredient called closure.

Ruby language defines Closure in sweet and simple form in its unix man page as objectify the procedure.

That is what we are going to do in Perl and JavaScript as below.

use strict;
use warnings;

sub Emp {

	# class level variables
	my $objCounter = 0;

	return sub {

		# the actual constructor
		my ($empid, $fname, $lname) = @_;
		return undef if not defined $empid;
		$objCounter++;
		$fname = ''  if not defined $fname;
		$lname = ''  if not defined $lname;

		# return a hash of public methods
		return {

			# object methods
			getEmpId => sub {return $empid},
			setFName => sub {$fname = shift},
			getFName => sub { return $fname},
			setLName => sub {$lname = shift},
			getLName => sub { return $lname},

			# a class method
			getObjCounter => sub { return $objCounter},
		}
	}
}

# the Emp() function should be called only once
# so that the class-level variables work as expected
# OR you could use feature 'state';
my $Emp_Constructor = Emp();

my $e1 = $Emp_Constructor->(100, 'Hello', 'World');
print 'Objects created = ', $e1->{getObjCounter}(), "\n";

my $e2 = $Emp_Constructor->(200);

# Class methods can be called with any object
print 'Objects created = ', $e1->{getObjCounter}(), "\n";
print 'Objects created = ', $e2->{getObjCounter}(), "\n";

print $e1->{getEmpId}(), ' ', $e1->{getFName}(), "\n";
$e1->{setFName}('myname');
print $e1->{getEmpId}(), ' ', $e1->{getFName}(), "\n";

print $e2->{getEmpId}(), ' ', $e2->{getFName}(), "\n";
$e2->{setFName}('yourname');
print $e2->{getEmpId}(), ' ', $e2->{getFName}(), "\n";

print $e1->{getEmpId}(), ' ', $e1->{getFName}(), "\n";

JavaScript code looks less noisier than Perl.
And in JavaScript, both Associate Arrays (i.e. Perl hashes) and Objects can be constructed with the same object literal syntax.

function Emp() {
    var objCounter = 0;
    return function(EmpID, FName, LName) {
        if(EmpID == undefined) return undefined;
        objCounter++;
        if(FName == undefined) FName = '';
        if(LName == undefined) LName = '';
        return {getEmpID: function(){return EmpID},
                getFName: function(){return FName},
                getLName: function(){return LName},
                setFName: function(X){FName = X},
                setLName: function(X){LName = X},
                getObjCounter: function(){return objCounter}
                }
    }
}

var EmpConstructor = Emp();
var e1 = EmpConstructor(100, 'Hello', 'World');
console.log('Objects created = ' + e1.getObjCounter());

var e2 = EmpConstructor(200);
console.log('Objects created = ' + e1.getObjCounter());
console.log('Objects created = ' + e2.getObjCounter());

console.log(e1.getEmpID() + '  ' + e1.getFName() + ' ' + e1.getLName());
e1.setFName('myname');
console.log(e1.getEmpID() + '  ' + e1.getFName() + ' ' + e1.getLName());

console.log(e2.getEmpID() + '  ' + e2.getFName() + ' ' + e2.getLName());
e2.setFName('yourname');
console.log(e2.getEmpID() + '  ' + e2.getFName() + ' ' + e2.getLName());

Erlang being a functional language, how could we achieve the same in it?

Happy Programming!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s