$main'O__C = 0 ; #Object Counter = number of allocated objet

#**************************************************************************#
package HashObject ;
#**************************************************************************#


#--------------------------------------------------------------------------#
	sub copy	{
		my $self = shift ;
		my $copy = $self->new() ;
		foreach $name (@{$self->fieldsNames()})	{
			$copy->{$name} =  $self->{$name} ;
		}
		
		$copy ;
	}
	
#--------------------------------------------------------------------------#
	
	sub inspect	{
		my $self = shift;
		
		foreach $name (@{$self->allFieldsNames()})	{
			print STDERR "$name  => $self->{$name}\n" ;
		}
	}
#--------------------------------------------------------------------------#
	
	sub asDictionary	{ #answer a ref to a hash table
		my $self = shift;
		my %dict = () ;
		
		foreach $name (@{$self->all_field_names()})	{
			$dict{$name} = $self->{$name} ;
		}
		
		
		\%dict ;
	}
#--------------------------------------------------------------------------#
	
sub asArray	{ #answer a ref to an array with all fields
	my $self = shift;
		
	my @array =() ;
	
	foreach $name ((@{$self->fieldsNames()}))	{
		push(@array, $self->{$name})  ;
	}
		
		\@array ;
	}	

#--------------------------------------------------------------------------#
#answer all field name  defined in HashObject
sub fieldsNames
{
		my $self = shift;		
		[] ; #answer an empty array
}
#--------------------------------------------------------------------------#
#answer all field name defined also in super classes
sub allFieldsNames
{
		my $self = shift;
		
		[] ; #answer an empty array
}

#--------------------------------------------------------------------------#
	sub instanceSize	{ #answer the number of fields
		my $self = shift;
		my @array = @{$self->allFieldsNames()}  ;
		
		
		$#array + 1 ;
	}
#--------------------------------------------------------------------------#

sub readFromCurrentLine {
	
	my $class = shift ;
	my $newInstance = $class->new();
	
	$newInstance->readFromStringToSplit( $_) ;

	return $newInstance ;
}
#--------------------------------------------------------------------------#
sub readFromInputFile
{
	my $class = shift () ;
	my $filename = shift ;
	defined $filename || die "Assertion failed";
	
	local *STDIN ;  
	open( STDIN, "$filename" ) || die "Can't open $filename" ;
	
	my $newInstance = $class->readFromInput() ;
	
	close (STDIN) ;	

	return $newInstance ;	

}
#--------------------------------------------------------------------------#
sub writeToOutputFile
{
	my $self = shift () ;
	my $filename = shift ;
	defined $filename && defined $self || die "Assertion failed";
	
	local *STDOUT ;
	
	open(STDOUT, ">$filename") || die "Can't open $filename for writing";
	$self->write() ;
	
	close (STDOUT) ;	

	$self ;
}#--------------------------------------------------------------------------#

sub readFromStringToSplit {
	$self = shift ;
	local $_ = shift ;
	
	defined $_ || die "Undefined argument";	
	

	my @fields = split ;
	
	if( $#fields +1 <  $self->instanceSize()  ) {
		main'global_error( "Line parsing error: not enough fields\n $_\n" );
	}
		
	foreach $name ((@{$self->allFieldsNames()}))	{
		$self->{$name} = shift @fields ;
	}
	
	$self; 		

}

#--------------------------------------------------------------------------#
# answer all fields joined in a string
sub joinedString
{

	my $self = shift ;

	join( " ", @{$self->asArray()})

}

#--------------------------------------------------------------------------#

sub printOnStream
{
	my $self = shift ;
	local *STDOUT = shift  ;
	
	my $string = $self ->joinedString() ;
	print $string ;
	print "\n" ;
	
	$self ;
}
		



#--------------------------------------------------------------------------#
	
	$new_SubClass_String	=
	'

        		sub new {
           		     my $new_instance = {}; 
					 my $class = shift ;
					 my $class = ref($class) || $class ; #Perl 2nd ed , p. 295
		
					if( defined $class)
					{	bless $new_instance, $class ;}
					else
					{ bless $new_instance ;}
										
					$main\'O__C ++ ; #Object Counter = number of allocated objet
					#printf STDERR " \$O__C = %d\n", $O__C ;

					$new_instance ;
        		}
	#sub DESTROY	{ my $self = shift; print STDERR ref($self), " destroyed\n" ; $main\'O__C -- ; } ;
	#sub DESTROY	{printf STDERR "Destroyed : %d\n" , $main\'O__C -- ;}
	sub DESTROY	{ $main\'O__C -- ;}

	
				sub fieldsNames	{ \@fields_names ; }  
				

	foreach $field (@fields_names)
	{
		#print STDERR "Creating function get for $field\n";
		my $string =  sprintf("\n sub %s {my \$self =shift ; \$self->{\"%s\"};} 1;\n", $field, $field) ; 
		#print STDERR $string ;
		eval($string) || die "Syntax error in $string  \n\n ";
		$string =  sprintf("\n sub set_%s {my \$self =shift ; my \$arg =shift; \$self->{\"%s\"} = \$arg;} 1;\n", $field, $field) ; 
		eval($string) || die "Syntax error in $string  \n\n ";

	}
	
#answer all field name defined also in super classes
sub allFieldsNames
{
		my $self = shift;
		my @array = (@fields_names, @{$self->SUPER::allFieldsNames()});
		
		\@array ;
}
	
	1;
' ;	
	
1 ;
