Forum: Ruby How to know if a method is read-write or read-only

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2005-12-18 23:50
(Received via mailing list)
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.
06c1bab0fb222c7426c02887cd728936?d=identicon&s=25 Johannes Friestad (Guest)
on 2005-12-19 01:05
(Received via mailing list)
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
5da4c52f43677f395aff5bde775593c2?d=identicon&s=25 Daniel Schierbeck (dasch)
on 2005-12-19 14:08
(Received via mailing list)
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
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Trans (Guest)
on 2005-12-21 01:25
(Received via mailing list)
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.
This topic is locked and can not be replied to.