comp.lang.ada
 help / color / mirror / Atom feed
* Virtual Components in Ada and Ruby
@ 2005-06-22 15:17 Frank J. Lhota
  2005-06-30  4:12 ` Randy Brukardt
  0 siblings, 1 reply; 6+ messages in thread
From: Frank J. Lhota @ 2005-06-22 15:17 UTC (permalink / raw)


Recently I was studying the Ruby scripting language. One of the features
of the Ruby language has a parallel in Ada. A Ruby class has one or more
"attributes", which are used to read or manipulate the data in an object.

A Ruby attribute is readable if it can be used to read a value
associated with an object. The book "Programming Ruby" uses the example
of a class Song, used to represent a song that included in a Jukebox. A
readable attribute of the Song class might be durationInSeconds. If
thisSong is an instance of Song class, a Ruby programmer could write a
statement like this to increment totalDuration by the duration of thisSong:

	totalDuration += thisSong.durationInSeconds

Conversely, a Ruby attribute is writable if it can be assigned a value.
If the durationInSeconds attribute of the Song class is writable, we
could write a statement such as this

	thisSong.durationInSeconds = 190

Ruby attributes look like record components, and many Ruby attributes
are in fact implemented using instance variables (the Ruby equivalent of
Ada record components). But Ruby also support virtual attributes, that
is, attributes that do not correspond to any actual instance variable.
Instead, a virtual attribute provides methods for reading and / or
writing that attribute. To illustrate, let us go back to our Song
example. This class has the durationInSeconds attribute, implemented as
an instance variable. Assume that in some programs, it is more useful to
work with a song's duration in minutes. We therefore would like to have
a readable / writable attribute called durationInMinutes. Obviously, it
would not be desirable to implement the durationInMinutes attribute with
another instance variable, since we would then have two instance
variables that must always be updated in tandem. A better approach would
be to implement durationInMinutes as follows:

      class Song
        # Read the virtual attribute durationInMinutes
        def durationInMinutes
          @durationInSeconds/60.0
        end
        # Write the virtual attribute durationInMinutes
        def durationInMinutes=(value)
          @durationInSeconds = value*60.0
        end
      end

Basically, this approach implements reading and writing the
durationInMinutes by performing the appropriate action on the
durationInSeconds instance variable. Of course, whether or not an
attribute is virtual is an internal implementation issue. Outside of the
Song class, the durationInMinutes attribute is used exactly the same way
as the durationInSeconds attribute.

So what does this have to do with Ada? Well, one could argue that the
notion of virtual components has existed in Ada from the very beginning.
Consider a packed record, such as the following:

      subtype Seconds_Count is Natural range 0 .. 59;
      subtype Minutes_Count is Natural range 0 .. 59;
      ...
      type Timestamp is
         record
            Sec : Seconds_Count;
	   Min : Minutes_Count;
            ...
         end record;

      for Timestamp use
         record
            Sec at 0 range  0 ..  5;
	   Min at 0 range  6 .. 11;
            ...
         end record;

Technically, the type of the Min component in Timestamp is Integer. But
Min is not really implemented as an integer in memory. Min is shorter
than an integer, and it does not even start on a byte boundary, much
less meet any byte alignment requirements for an integer. Min is
definitely not aliased. The Ada compiler, however, makes it look as
though Min is an integer by using mask and shift procedures to read and
write integer values for Min. For example, if TS is an object of type
Timestamp, the Ada statement

      Ada.Integer_Text_Io.Put (TS.Min);

is often (always?) implemented by having the compiler retrieve the
integer value of TS.Min using mask and shift, then passing that integer
to the "Put" procedure. Similarly,

      TS.Min := Some_Integer;

is implemented by a mask and shirt to store Some_Integer into the bits 
for Min. Borrowing from the Ruby terminology, Min is a virtual component.

Looking ahead to Ada 201Z, should there be user-defined virtual record 
components? Currently, a component of a record must always be defined as 
a section of memory in a record. Would it be desirable to also be able 
to define a record component in terms of subprograms for reading and 
writing that component?

Last year, I had a similar proposal for virtual record components:

http://groups-beta.google.com/group/comp.lang.ada/browse_thread/thread/b5ab7c96b188b59e/83840467bdfa413f?q=Lhota&rnum=2#83840467bdfa413f



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-07-01 10:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-22 15:17 Virtual Components in Ada and Ruby Frank J. Lhota
2005-06-30  4:12 ` Randy Brukardt
2005-06-30  7:53   ` Dmitry A. Kazakov
2005-06-30 15:53     ` Alexander E. Kopilovich
2005-06-30 18:55       ` Randy Brukardt
2005-07-01 10:04         ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox