tags:

views:

99

answers:

3

Is there a tool to check if a Python code conforms to the law of Demeter?

I found a mention of Demeter in pychecker, but it seems that the tool understands this law different to what I expect: http://en.wikipedia.org/wiki/Law_of_Demeter

The definition from wikipedia: the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:

  1. O itself
  2. M's parameters
  3. any objects created/instantiated within M
  4. O's direct component objects
  5. a global variable, accessible by O, in the scope of M
+1  A: 

The way this law is explained in the link you provide it is far too vague and subjective to be efficiently checked by any automated tool. You would need to think of specific rules that lead to code that abides by this law. Then you can check for these rules.

Space_C0wb0y
Disagree. You would need to think of specific ways to **break** these rules in Python. Then find ways to spot this. I don't think it's terribly easy to break these rules.
S.Lott
A: 

law of Demeter ... method M of an object O may only invoke the methods of the following kinds of objects:

  1. O itself -- i.e. self variables. Easy to see.
  2. M's parameters -- i.e., local variables given by the parameters. That is to say, in locals()
  3. any objects created/instantiated within M -- i.e., local variables. That is to say, in locals()
  4. O's direct component objects -- i.e., self variables.
  5. a global variable, accessible by O, in the scope of M -- i.e., variables named in a global statement or implicit references to globals that are not found in the local namespace. That is to say in globals().

Ummm.... There are no other variables accessible to a function, are there? Because of the way namespaces work, I don't see any possibility for breaking this law.

Do you have an example of Python code that breaks one of these rules?

How would you get access to another namespace?

S.Lott
def someMethod(): // o = self.GetSomeObject() // x = o.SomeMethod() // o is not instantiated within someMethod, it is got from some function
@user327725: Isn't that Rule 3. Any objects created/instantiated within `M`? How is it not rule 3?
S.Lott
No, it is not rule 3 because the object is created not in "someMethod", but somewhere in "GetSomeObejct".
A: 

You could probably break that law like this:

class SomeClass:
    def someMethod(self):
        self.getSomeOtherClass().someOtherMethod() # this breaks the law
    def getSomeOtherClass(self):
        class_ = SomeOtherClass()
        return class_

Or no?

Richard Knop
no because some other class is available in `globals()` to begin with. There's no need for all the complexity.
aaronasterling
I think you're on to something. If the other class was brought in via `execfile`, that would clearly break the law. That's an object not even visible in the source code.
S.Lott