Setting and getting methods and variables

E

erlercw

Object#instance_variable_set
Object#instance_variable_get
Object#methods
Module#define_method
Module#remove_method
Module#undef_method

and all the other similar methods suffer from being scattered
through several classes and naming inconsistencies.
#instance_variable_set is not only noun-verb, the opposite of
most method names, set is also different than define. Also,
what's the difference between remove and undef ? It's not easy
to tell on first glance and the help at ruby-doc.org is a bit
misleading.

The main problem is that it seems like a bunch of hackish
workarounds that were added after the language was designed.
Java needs things like utility classes and long, wordy names,
because it was badly designed. Ruby doesn't need to suffer the
same problems.

I propose a more streamlined way of changing methods and
instance variables on the fly: treat them like hashes. This
doesn't have to affect the inner workings of Ruby, just the
programmer's interface to Ruby.

For instance, object_or_class.private_instance_methods should
return a reference to the object or class MethodHash. This
will allow easily adding new methods or getting old methods
without obscure incantations. The same kind of things could be
done with instance and class variables (perhaps with a normal
Hash or VariableHash).

MethodHash#merge would be an easy way to do advanced things
similar to mixing in modules (although the current method of
actually mixing in modules works fine and should be kept).

MethodHash#delete would be an easy way to do
Object#remove_method; hash[:method] = nil should also work. I
propose leaving two ways to do Object#undef_method: provide
Object#undef_method (or something with a better name like
#forget_method or #block_method) that will set the method in
the MethodHash to false (conceptually, Ruby looks at the
object's methods first, and false would make the point clear to
Ruby and programmers). This will allow people to figure out
how to block a method just by looking at method names and also
allow a somewhat intuitive way of blocking to those who don't
like memorizing method names.

MethodHash#keys would do the same thing as the array-returning
methods (that list methods) do now.

This would make Ruby much less Java-like (verbose and no nice
features like #[] and #[]= outside of arrays). It would remove
the need to learn which arcane incantation you need (and allow
for Ruby's designers not to have to waste time thinking up
names) for private instance methods compared to instance
methods (Do I use 'set' or 'define' here ? Does the verb come
first or last ? etc). Plus, it would be, like blocks and
iterators, easier to learn and apply in Ruby than most other
languages. It would also reduce the time I need to spend
looking in Pickaxe for method names.

I'm planning on making this an RCR, but I wanted to hear a bit
of criticism to help me shape the RCR.
 
D

David A. Black

Hi --

Object#instance_variable_set
Object#instance_variable_get
Object#methods
Module#define_method
Module#remove_method
Module#undef_method

and all the other similar methods suffer from being scattered
through several classes and naming inconsistencies.

They sort of have to be scattered through different classes; the
instance variable ones belong to every object, as do some of the
universal *methods ones (methods, private_methods, etc.), whereas
things like instance_methods etc. are for class/module reflection.
(I'm a big fan of "classes are just objects" philosophy, but they do
sometimes need special equipment :)
#instance_variable_set is not only noun-verb, the opposite of
most method names, set is also different than define.

It is different, though. I don't think one speaks of "defining" an
instance variable with a particular value, but rather setting it to a
value. Similarly I don't think one speaks of "setting" a method. And
once a variable is defined, you can set it repeatedly; they're two
different operations.
Also,
what's the difference between remove and undef ? It's not easy
to tell on first glance and the help at ruby-doc.org is a bit
misleading.

It's OK for more than one glance to be required for a fairly powerful
feature -- the Ruby learning curve is still pretty good [i.e., steep
or shallow, depending how you interpret the 'learning curve'
metaphor] :) The description ri gives seems pretty thorough. You
should let James Britt know what the problems are at ruby-doc.
The main problem is that it seems like a bunch of hackish
workarounds that were added after the language was designed.
Java needs things like utility classes and long, wordy names,
because it was badly designed. Ruby doesn't need to suffer the
same problems.

I propose a more streamlined way of changing methods and
instance variables on the fly: treat them like hashes. This
doesn't have to affect the inner workings of Ruby, just the
programmer's interface to Ruby.

For instance, object_or_class.private_instance_methods should
return a reference to the object or class MethodHash.

Do you mean module_or_class? In the general case (i.e.,
non-Module/Class), objects don't have instance_methods methods, since
all of their methods are instance methods (including class methods, if
you happen to be a Class).
This
will allow easily adding new methods or getting old methods
without obscure incantations. The same kind of things could be
done with instance and class variables (perhaps with a normal
Hash or VariableHash).

MethodHash#merge would be an easy way to do advanced things
similar to mixing in modules (although the current method of
actually mixing in modules works fine and should be kept).

I like hash-like interfaces in general, but I'm just wondering whether
this would create a kind of parallel-universe type system (or at least
semantics) and actually complicate the situation. I don't know.
MethodHash#delete would be an easy way to do
Object#remove_method; hash[:method] = nil should also work. I
propose leaving two ways to do Object#undef_method: provide
Object#undef_method (or something with a better name like
#forget_method or #block_method) that will set the method in
the MethodHash to false (conceptually, Ruby looks at the
object's methods first, and false would make the point clear to
Ruby and programmers). This will allow people to figure out
how to block a method just by looking at method names and also
allow a somewhat intuitive way of blocking to those who don't
like memorizing method names.

A couple of questions about that:

1. What would happen to the current distinction betweeen
#remove_method and #undef_method?
2. If the hash value is set to nil or false -- rather than
the key/value being deleted entirely -- what would happen
here?

def obj.x; end
obj.methods[:x] = false
obj.methods.keys.include?:)x) # true or false?

This would make it hard to do certain types of reflection, I think.
(It also seems a bit roundabout to have to do a call to #keys just to
get a list of the method names, if I'm getting that right.)
MethodHash#keys would do the same thing as the array-returning
methods (that list methods) do now.

This would make Ruby much less Java-like (verbose and no nice
features like #[] and #[]= outside of arrays).

I think there are some intra-Ruby reasons for some of these things.
For example, instance_variable_[gs]et, from what I understand, is
deliberately somewhat awkward, as a tangible manifestation of the fact
that it isn't generally a good idea to pry into other objects'
instance variables. This is an example of what I view as the triumph
of balance over symmetry -- something I think Matz is brilliant at.


David
 
C

Csaba Henk

Object#instance_variable_set
Object#instance_variable_get
Object#methods
Module#define_method
Module#remove_method
Module#undef_method

and all the other similar methods suffer from being scattered
through several classes and naming inconsistencies.
#instance_variable_set is not only noun-verb, the opposite of
most method names, set is also different than define. Also,
what's the difference between remove and undef ? It's not easy
to tell on first glance and the help at ruby-doc.org is a bit
misleading.

The main problem is that it seems like a bunch of hackish
workarounds that were added after the language was designed.
Java needs things like utility classes and long, wordy names,
because it was badly designed. Ruby doesn't need to suffer the
same problems.

Either way, I don't feel these method names as problematic as they
should be changed.
I propose a more streamlined way of changing methods and
instance variables on the fly: treat them like hashes. This
doesn't have to affect the inner workings of Ruby, just the
programmer's interface to Ruby.

These are quite sugared away from sight by the keywords one usually uses
to perform these actions. In everyday codig you rarely get to the point
where you need to use these explicitly. In these cases, I don't feel the
usage of the above being a pain.
For instance, object_or_class.private_instance_methods should
return a reference to the object or class MethodHash. This
will allow easily adding new methods or getting old methods
without obscure incantations. The same kind of things could be
done with instance and class variables (perhaps with a normal
Hash or VariableHash). [snip]
MethodHash#keys would do the same thing as the array-returning
methods (that list methods) do now.

Do I understand correctly that you propose a proxy hash for modifying
the object in the above mentioned ways? If so, that seems to be
non-orthogonal, and quite an intrusion to Ruby internals. Let the object
take care of itself. It's a simple idea, and ruby owes its flexibility
for keeping things simple.
languages. It would also reduce the time I need to spend
looking in Pickaxe for method names.

Why don't just use the method name completion feature of irb?

Csaba
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top