Language Comparison – Properties

It’s generally accepted wisdom by now that giving client objects direct access to data stored on a class is a bad idea; it violates encapsulation, prevents you from changing implementations in interface-neutral ways, and prevents you from doing other things like lazy-computation or evaluation that might eventually prove necessary for the sake of correctness or performance. In addition, it’s often useful to have operations that look like simple field gets and sets but that actually do additional logic and aren’t tied to any particular data value.

Most modern languages, then, have adopted conventions and/or techniques around using methods to expose private data. In Java, for example, the standard approach is to make all instance variables private and to use get/set/is methods to access and manipulate the data instead. It’s a very useful convention, but it’s such a fundamental pattern that other languages have gone even further by making it possible to expose methods that look like variable accesses, allowing for variable-like accesses and assignments. The names aren’t the same across all languages, but I’ll use the term “property” to refer to get/set methods that are exposed as simple variable accesses, since that seems to be the most common term. So let’s look at how you go about defining and using properties in each language. The use case, for illustration purposes, will be a User object that has a Name property.

Java

Java doesn’t have built-in support for properties, so you have to define the getters/setters yourself:

private String _name;
public String getName() { return _name; }
public void setName(String name) { _name = name; }

Similarly, to access the property you have to call the method:

user.setName("Bob");
System.out.println("Hello, my name is " + user.getName());

The Java introspector, used for JavaBeans, will combine the getName() and setName() methods into a single Name property that is both readable and writable, so for the sake of reflective access using BeanInfo there is some concept of a property. Not at the source code level, though.

GScript

GScript has a first-class notion of properties, allowing you to declare things like so:

var _name : String
property get Name() : String { return _name }
property set Name(name : String) { _name = name }

Since defining a property to wrap a private variable is such a common pattern, there’s also a shorthand notation for that:

var _name : String as Name

Which is equivalent to the above declarations. You can also start by using the “as” syntax and then explicitly define the property getter or setter if you like. Using the properties is what you’d expect:

user.Name = "Bob"
print("Hello, my name is " + user.Name)

There are a couple of other things worth noting here. First of all, GScript follows the JavaBeans naming convention that properties start with a capital letter, which helps make clear that they’re properties and not instance variables. Secondly, GScript exposes Java classes the same way the Java introspector does, so a Java class with getName() and setName() methods will, from GScript, appear to have a Name property instead of getName() and setName() methods.

Ruby

All instance variables in Ruby are private, and the only way to expose them is via a method. Ruby makes parentheses optional on method calls, allows white space in all sorts of places, and allows all sorts of interesting characters to be used in method names, so ‘=’ is actually a valid character in a method definition. So you could do things in a brute-force manner like:

def name
  @name
end

def name=(val)
  @name = val
end

Note that in the second case, the = character is part of the method name; including = in a method name makes it possible for it to appear on the left-hand side of an assignment statement. I don’t actually know Ruby well enough to say if that’s built in to the parser or just a result of the fact that parentheses are optional and whitespace is permitted in interesting places.

Since this is such a common pattern, Ruby has built-in methods for creating what Ruby calls “attributes,” their name for the property concept. The methods are just like any other Ruby method and use metaprogramming to dynamically create the getter/setter methods. So the above code could be simplified down to:

attr_accessor(:name)

Note that this makes use of Ruby’s concept of symbols (that’s what :name is; the ‘:’ character at the start denotes this as a symbol), which are used all over the place for metaprogramming in Ruby.

Accessing the attributes in Ruby looks like what you’d expect:

user.name = "Bob"
puts "Hello, my name is ${user.name}"

Python

Python’s notion of properties is a bit more complicated; in fact, despite reading through all the chapters on object-orientation in Dive Into Python I didn’t know it existed until I read through the Django Database API documentation and clicked through to see how they managed to make their foreign-key references work.

It turns out that Python’s support for properties is via a general-purpose mechanism called Descriptors. Descriptors are used for much more than just properties, but in the context of properties they’re a bit hard to understand since they turn things kind of on their head. A descriptor is an object that has special methods that define what to do when the object is treated like a variable and is accessed, set, or deleted (since that’s possible in Python). So instead of defining getName/setName methods on the User class, in Python what you do is create a descriptor object that’s bound to the class-level “name” variable, and then when that class-level variable is accessed or assigned to the methods on the “name” descriptor object will be invoked. Don’t feel bad if your response to that is “Huh?”

There’s a built-in method called “property” in Python that lets you create a descriptor given the function parameters, so to define the “name” property on the User class in Python you would do:

def get_name(self): return self.__name
def set_name(self, value): self.__name = value
name = property(get_name, set_name)

So what this means is that name is an object, and that object will call back to the get_name on User when it is accessed and to set_name when it’s assigned to. It gets the job done, but not as elegantly as in Ruby or GScript in my opinion; it feels like the bolts are showing a little bit.

The use of the property, though, looks like what you’d expect:

user.name = "Bob"
print "Hello my name is %s" % user.name

5 Comments on “Language Comparison – Properties”

  1. Raoul Duke says:

    When I heard that Scala defaults to things being public it sure set of alarms in my head, but I’ve heard it from people who are in the know that it all works out just fine. Hm. (Hey, what is up with this blog comment entry form where the right-hand side of the text I’m entering here is chopped off by the edge of the text box, as if there should be a horizontal scroll bar, but there isn’t?)

  2. Alan Keefer says:

    GScript is similar in that it defaults functions to public and instance variables to private, since that’s generally what you want. For instance variables that’s probably what you always want, especially given the ease of exposing them as properties. For methods it’s debatable since you’ll probably want a lot of private ones, but at least it’s a more sensible default than the package-protected default that Java uses.

    As to the comment box, I haven’t had a problem with it . . . my text wraps properly and doesn’t get cut off. I’m using FireFox 2, so perhaps it’s a browser issue? (And for what it’s worth, your comment did get posted twice, so I’m guessing WordPress just freaked out on you temporarily and didn’t show it the first time you posed it.)

  3. Sebastian Wittenkamp says:

    Just one minor typo…

    In this line, you need to replace the ‘$’ with an ‘#’
    puts “Hello, my name is ${user.name}”

    Otherwise, the puts will evaluate to exactly what you typed, and not insert “Bob”.

  4. Well, actually in python, if you’re going to just have a simple property (getter and setter), it’s encouraged to keep it plain and simple.

    class A():
    def __init__(self):
    self.name = ‘bob’

    a = A()
    a.name = ‘joe’

    You can always later change the implementation and still have ‘name’ exposed.

    Properties are used most of the time to mark _methods_ as variables:

    class B():
    @property
    def count(self):
    return len(self.array)

    you can then use

    print B().count

    but not

    B().count = 3

    This is the most commonly used read-only attribute pattern, IME

  5. WordPress ate my whitespace 😦


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