A method M of an object O may only invoke the methods of the following kinds of objects:
For all classes C, and all methods M attached to C, all objects to which M sends a message must be
(Objects created by M, or by functions or methods which M calls, and objects in global variables are considered as arguments of M.)
For all classes C, and all methods M attached to C, all objects to which M sends a message must be
(Objects created by M, or by functions or methods which M calls, and objects in global variables are considered as arguments of M.)
The Law prohibits the nesting of generic accessor function calls, which return objects that are not instance variable objects. It allows the nesting of constructor function calls. An accessor function is a function which returns an object which did exist before the function is called. A constructor function returns an object which did not exist before the function is called.
Writing programs which follow the Law of Demeter … increases the number of methods. [This] is related to the problem outlined in [12] which is that there can be too many operations on a type.
One way of correcting this problem is to organize all the methods associated with a particular functional (or algorithmic) task into “Modula-2 like” module structures as outlined in [11].
a module is a grouping of variables, constants, types, and procedures
http://www.modula2.org/tutor/chapter12.php
# Automatic "Demeter Transmogrifier"
def method_missing(sym, *args, &block)
parts = sym.to_s.split '_'
(parts.size - 1).downto 1 do |i|
prefix = parts[0...i].join '_'
suffix = parts[i..-1].join '_'
break send(prefix).send(suffix, *args, &block) if respond_to? prefix
end
end
[".elur diputs a s'tI"].first_reverse
# Automatic conversion to Demeter-style
def require(base_name)
if $".include? base_name
false
else
file = $:.map {|dir| File.join dir, "#{base_name}.rb" }.find {|file| File.exist? file }
code = IO.read file
code.gsub! /\.(.+)\./, '.\1_'
Object.module_eval code, file, 1
true
end
end
open('foo.rb', 'w') {|f| f.puts '[".esnes nommoc esu tsuJ"].first.reverse' }
require 'foo'