I've now come across a second usecase for knowing if a method is read-write or read-only on it's object's state. Both cases boil-down to having meta-method behave differently depending on the behavior of method being delegated to, but the circumstances differ completely. To give an example, the current case generates method wraps for any given class, applying thread sycronization. If a method is read-only it's wraped in a Sync::SH, if read-write then Sync::Ex. So I wonder, is there a way to determine this fact about a method? Thanks, T.
on 2005-12-18 23:50
on 2005-12-19 01:05
I assume you mean methods that are property getters/setters, along the lines of 'user.name()'/'user.name=(name)', and that read-write or read-only refer to object properties like 'name'? There is no general way to determine whether a method updates object state or not. (Unless you start parsing bytecodes or hook into the VM parse tree, which is a somewhat larger project.) You'll have to rely on naming conventions, like "a method that takes no arguments and has a name not ending with '=' is a getter, a method that takes one argument and has a name ending with '=' is a setter". You can get the number of arguments from Method#arity, like Array.instance_method(:length).arity => 0 jf
on 2005-12-19 14:08
Trans wrote: > Thanks, > T. > Do you want to know if a method changes its object's state? In that case, you could duplicate the object, freeze the duplicate and try to call the method. If an Exception is raised, then either the method has a bug or it is state-changing. class Object def changes_state?(method) self.dup.freeze.send(method) return false rescue TypeError return true end end "foo".changes_state? :upcase => false "foo".changes_state? :upcase! => true It would be nice if a special exception was thrown when attempting to call a method on a frozen object, so that you could distinguish it from the usual TypeErrors. Note that this method isn't very efficient, since it duplicates the entire object on each invocation. If you were to check many methods on a single object, you might want to keep the frozen duplicate in an instance variable. Cheers, Daniel
on 2005-12-21 01:25
Thanks Daniel. That's an interesting approach --probably the best automatic way that can be done. But I think for a practical approach I will have to create some sort of annotation declaration and simply manually declare methods as read-only vs. read-write. Not ideal, of course, but at least it will work efficiently. Thanks, T.