# How to know if a method is read-write or read-only

**URL:** <https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604>\
**Category:** Ruby\
**Created:** [December 18, 2005, 11:50pm UTC](https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604 "2005-12-18T23:50:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 18, 2005, 11:50pm UTC](https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604/1 "2005-12-18T23:50:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 19, 2005, 1:05am UTC](https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604/2 "2005-12-19T01:05:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 19, 2005, 2:08pm UTC](https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604/3 "2005-12-19T14:08:19Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [December 21, 2005, 1:25am UTC](https://www.ruby-forum.com/t/how-to-know-if-a-method-is-read-write-or-read-only/50604/4 "2005-12-21T01:25:44Z")

</div>

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.
