Best name for "this method" ?

V

vruz

1) It's a pronoun
I think your initial reaction was right :) With things like this, I
usually run through in my mind what it would be like to teach it to a
new Rubyist. I think trying to explain "self" and "me" would be
awkward.

"me" should be pretty mnemotechnical for method
I would find it hard to forget that way



--- vruz
 
J

Jim Haungs

I'll preface this with saying I don't know Ruby yet as well as I know
Smalltalk, so please correct any fine points I get wrong.

In Smalltalk, the calling context is called "thisContext" because it
can be either a method or a block. And it returns an actual context
object, which are represented by a class in Smalltalk, but which are
not (as far as I can tell) reified in Ruby.

So if you implemented it in Ruby, you'd have to decide whether it
referred to the block context or the enclosing method context,
and you'd have to invent a reification of the dynamic execution
context, as the method name by itself isn't very useful.

I'd certainly think twice about adding it to the language. What you
explicitly leave out of a language is as important as what you put in.

In 20+ years of reading and writing Smalltalk, I've hardly ever used
it or seen it used except for writing debuggers and similar tools that
deal with dynamic execution state.

I wanted to include some statistics on its use in Smalltalk, but
unfortunately, it's not a true message send in VisualWorks; it's
inlined by the compiler. So you'd have to write some bytecode scanning
code to find where it's called (which might be fun!)

trans. (T. Onoma) said:
Wondering what the conscensus is on the best name for "this method". Right now
I'm using #calling, taking after #binding, but I'm not so sure about it. I've
also considered #this or #thus, to be more along the lines of 'self'.

JavaScript uses callee for the first-class version.
# Returns the current method or method name
def calling(firstclass=false)
m = /\`([^\']+)\'/.match(caller(1).first)[1]
return ( firstclass ? method( m ) : m.intern )
end

Personally, I'd dump the first-class logic and call it method_name. It
is easy enough to turn that into a Method anyway.
Also, will a method like this be implemented in future Ruby?

I'm not sure about this. (Is it needed frequently?) But right now I'd
prefer Binding.of_caller to be in Ruby itself. After all it is needed
for wrapping eval() and it can not be done with a pretty interface in
plain Ruby. (It can be done in Ruby if you turn it inside out, e.g. make
it yield a value instead of returning it.)
Thanks,
T.

Regards,
Florian Gross
 
R

Robert Klemme

vruz said:
"me" should be pretty mnemotechnical for method
I would find it hard to forget that way

Perl name clash alarm! Seriously, I don't think "me" is appropriate. I
would usually expect it to denote an instance and not a method. Also, it
sounds like an alias for "self" rather than "this method".

Kind regards

robert
 
R

Robert Klemme

trans. (T. Onoma) said:
Actually, I agree with you too. Since it's just a flag, perhaps using
meaningful symbols would be better?

methods:)public)
methods:)private)
methods:)protected)

methods:)no_ancestors)
methods:)ancestors_only)

methods:)class) # same as self.class.methods ?
methods:)singleton)

And they could be combined:

methods:)private, :protected)
methods:)singleton, :private)
methods:)private, :no_ancestors)

Combining the results is the only advantage of this approach. Still I
prefer simple and short method implementations (which are less error prone
and often more efficient). So if you use symbols, change method names:

public_methods()
private_methods()
protected_methods()

local_methods()
inherited_methods()

drop: methods:)class) # same as self.class.methods ?

singleton_methods()

You can still combine these by concatenating invocation results. I think
usually this is not necessary

Kind regards

robert
 
F

Florian Gross

trans. (T. Onoma) said:
JavaScript uses callee for the first-class version.

# Returns the current method or method name
def calling(firstclass=false)
m = /\`([^\']+)\'/.match(caller(1).first)[1]
return ( firstclass ? method( m ) : m.intern )
end

Personally, I'd dump the first-class logic and call it method_name. It
is easy enough to turn that into a Method anyway.

Then what about #called for just the method name?

def my_method
p called
end

Why not method_name? called() is a bit ambiguous IMHO...

Regards,
Florian Gross
 
F

Florian Gross

trans. (T. Onoma) said:
Okay, I see. I did some research to understand. The problem I see with this is
that it might have too large an overhead --in effect creating a binding prior
to every method invocation. Is that so? On the other hand, I see no reason
for 'self' of caller not to be available.

Why? As you can see from my trace_func implementation Ruby already knows
how to fetch the binding on demand (via ruby_frame->prev) -- it just
doesn't provide a way to do it from within Ruby.

Regards,
Florian Gross
 
G

Gavin Sinclair

Combining the results is the only advantage of this approach. Still I
prefer simple and short method implementations (which are less error prone
and often more efficient). So if you use symbols, change method names:


drop: methods:)class) # same as self.class.methods ?
singleton_methods()

I completely disagree, Robert. Lots of related methods is a code smell
to my nose. Elegant solutions are generally well factored, rather than
expanded all over the top level. One should aim to keep like things
together, and different things apart.

There are two possible factorings. Have Object#methods return a
specialised object, thus:

foo.methods.private
foo.methods.all
foo.methods.new
foo.methods.singleton
foo.methods[:new, :protected] # if you need combination
# etc.

The other possible factoring is as above:

foo.methods:)new)
foo.methods:)private)
foo.methods:)singleton, :private)
# etc.

Aesthetically, I think I prefer the top one. But even the second one
is far preferable to the current state of Ruby, to my mind.

In general, you dislike using symbolic arguments to tune a method's
behaviour. I like it, and consider it quite consistent with the
general practices of good programming.

Cheers,
Gavin
 
R

Robert Klemme

Gavin Sinclair said:
Combining the results is the only advantage of this approach. Still I
prefer simple and short method implementations (which are less error prone
and often more efficient). So if you use symbols, change method
names:
drop: methods:)class) # same as self.class.methods ?
singleton_methods()

I completely disagree, Robert. Lots of related methods is a code smell
to my nose. Elegant solutions are generally well factored, rather than
expanded all over the top level. One should aim to keep like things
together, and different things apart.

There are two possible factorings. Have Object#methods return a
specialised object, thus:

foo.methods.private
foo.methods.all
foo.methods.new
foo.methods.singleton
foo.methods[:new, :protected] # if you need combination
# etc.

The other possible factoring is as above:

foo.methods:)new)
foo.methods:)private)
foo.methods:)singleton, :private)
# etc.

Aesthetically, I think I prefer the top one. But even the second one
is far preferable to the current state of Ruby, to my mind.

In general, you dislike using symbolic arguments to tune a method's
behaviour. I like it, and consider it quite consistent with the
general practices of good programming.

Agree and disagree: after thinking a bit about the issue I think that
those symbol arguments are not as bad as I thought earlier because they
can be viewed as a filter criterion. Even if the implementaiton of
"method" would delegate to several other methods this seems ok to me.

I still have problems with the last, very general statement, unless you
mean only slight changes in behavior by "tune": when arguments (whatever
type they have) are used to vastly change a method's behavior then a
solution with several methods is superior: it's more modular, makes life
of sub class implementors easier who may need to override just one of
these methods, those several methods are likely shorter and thus less
susceptible to errors than the all-in-one method, there is likely a
performance gain because the code that figures what to do is obsolete etc.

I think my general line here would be, that "tuning" by arguments (i.e.
small changes in behavior) is ok, but that it becomes more problematic the
greater the differences are. There is no single measurable point that can
be used as a criterium in this case. As always the situation at hand must
be careful evaluated to find the most appropriate solution. It's
certainly an advantage to know both approaches and the pros and cons of
them.

Gavin, thanks for helping to sort this out!

Kind regards

robert
 
T

trans. (T. Onoma)

There are two possible factorings. Have Object#methods return a
specialised object, thus:

foo.methods.private
foo.methods.all
foo.methods.new
foo.methods.singleton
foo.methods[:new, :protected] # if you need combination
# etc.

For this approach, I think combinations would be better like:

foo.methods { |m| m.private | m.singleton }
foo.methods { |m| m.private + m.public }

But I think it might be a bit much to have a whole new class for this.

Sometimes I really wish symbolic keyed hashes were accessable like object
methods:

h = { a: 1, b: 2 }
h.a #=> 1
h.b #=> 2

That would be sweet. And would make the above possible without a new class. I
know, method name clash is bad --and there's little one can do to get around
it. Perhaps alternate notation?

h:a
h:b

But I digress.

T.
 
D

David A. Black

Hi --

h = { a: 1, b: 2 }
h.a #=> 1
h.b #=> 2

That would be sweet. And would make the above possible without a new class. I
know, method name clash is bad --and there's little one can do to get around
it. Perhaps alternate notation?

h:a
h:b

What's wrong with h[:a] ?


David
 
R

Robert Klemme

trans. (T. Onoma) said:
There are two possible factorings. Have Object#methods return a
specialised object, thus:

foo.methods.private
foo.methods.all
foo.methods.new
foo.methods.singleton
foo.methods[:new, :protected] # if you need combination
# etc.

For this approach, I think combinations would be better like:

foo.methods { |m| m.private | m.singleton }
foo.methods { |m| m.private + m.public }

But I think it might be a bit much to have a whole new class for this.

Sometimes I really wish symbolic keyed hashes were accessable like object
methods:

h = { a: 1, b: 2 }
h.a #=> 1
h.b #=> 2

You mean like this:
=> {:a=>2, :b=>3, :c=>100}

class SymHash < Hash
def method_missing(sym,*args)
key = sym.to_s.sub!(/=$/, '')
if key
self[key.to_sym]=args[0]
else
self[sym]
end
end
end
That would be sweet. And would make the above possible without a new class. I
know, method name clash is bad --and there's little one can do to get around
it. Perhaps alternate notation?

I'd rather not have another separator - "." and "::" is enough IMHO.
h:a
h:b

But I digress.

I guess so. :) But sometimes good ideas come from this.

Regards

robert
 
T

trans. (T. Onoma)

Why? As you can see from my trace_func implementation Ruby already knows
how to fetch the binding on demand (via ruby_frame->prev) -- it just
doesn't provide a way to do it from within Ruby.

Well, that's my question. Does it just retrieve a reference or does it have to
create the binding? If it's just grabbing a reference to an already existing
binding, that's fine, but then I don't see why using set_trace_function
should slow a program down as much as it does. So I'm guessing it has to
create a binding. Although ruby_frame->prev suggests it already exists.

I just don't know the internals well enough, and am wondering.

T.
 
A

Austin Ziegler

Combining the results is the only advantage of this approach. Still I
prefer simple and short method implementations (which are less error prone
and often more efficient). So if you use symbols, change method names:

public_methods()
private_methods()
protected_methods()

local_methods()
inherited_methods()

drop: methods:)class) # same as self.class.methods ?

singleton_methods()

You can still combine these by concatenating invocation results. I think
usually this is not necessary

This sounds like a lovely RCR candidate, Robert :)

-austin
 
T

trans. (T. Onoma)

You mean like this:
[snip]

class SymHash < Hash
def method_missing(sym,*args)
key = sym.to_s.sub!(/=$/, '')
if key
self[key.to_sym]=args[0]
else
self[sym]
end
end
end

I knew someone would show me that ;) I also have a simple #to_obj method for
Hash itself that I use. Alas, both have their shortcomings.
I'd rather not have another separator - "." and "::" is enough IMHO.

Agree. This was not really thought out.
I guess so. :) But sometimes good ideas come from this.

That's good b/c I'm a chronic digressor ;)

T.
 
T

trans. (T. Onoma)

Hi --

h = { a: 1, b: 2 }
h.a #=> 1
h.b #=> 2

That would be sweet. And would make the above possible without a new
class. I know, method name clash is bad --and there's little one can do
to get around it. Perhaps alternate notation?

h:a
h:b

What's wrong with h[:a] ?

Blech? No, it's okay. Having to use three chars when one will do is not so
sweet. But not big deal. So I take it back. Alternate is not thought out
and probably blech for other reasons.

T.
 
D

David A. Black

Hi --

Hi --

h = { a: 1, b: 2 }
h.a #=> 1
h.b #=> 2

That would be sweet. And would make the above possible without a new
class. I know, method name clash is bad --and there's little one can do
to get around it. Perhaps alternate notation?

h:a
h:b

What's wrong with h[:a] ?

Blech? No, it's okay. Having to use three chars when one will do is not so
sweet. But not big deal. So I take it back. Alternate is not thought out
and probably blech for other reasons.

I know it's tempting to want everything to be compressed, and to use
(low) character-count as a measure of success, but compressing things
can backfire. They get too compressed :) For example, I believe
your notation would run aground on this:

cond ? h : a

vs.

cond ? h:a : b

or

cond? h:a:b # what's what here?

etc.


David
 
F

Florian Gross

trans. (T. Onoma) said:
Well, that's my question. Does it just retrieve a reference or does it have to
create the binding? If it's just grabbing a reference to an already existing
binding, that's fine, but then I don't see why using set_trace_function
should slow a program down as much as it does. So I'm guessing it has to
create a binding. Although ruby_frame->prev suggests it already exists.

From my limited knowledge of the internals it would only have to tweak
a BLOCK and wrap it into a Binding object. That's still not costless of
course, but you only have to pay that performance cost when you're
actually using Binding.of_caller which is okay IMHO.

Regards,
Florian Gross
 
T

trans. (T. Onoma)

  foo.methods[:new, :protected]   # if you need combination

This line's got me thinking... How does one define a class [] constructor? For
example Hash can be use like this:

Hash[:a=>1,:b=>2 ]

And then I start to wonder why we can't just use the class name like a method?

Hash:)a=>1, :b=>2)

Of course, I also think the same of Procs themselves, and having to use call
(or []):

myproc = proc{2+2}
myproc() #=> 4

The potential name clashes don't seem a big enough blooper to me, but perhaps
I have forgotten another reason.

Anyway, once again I digress. My original point was simply this: Would it
behoove us to extend the [] construct on hashes to accept multiple
parameters? E.g.

h = { :a => 1, :b => 2, :c => 2 }
h[:a, :c] #=> [1,2]

This would make Gavin's above method notation nicely workable without a
special class.

T.

--
( o _ カラãƒ
// trans.
/ \ (e-mail address removed)

I don't give a damn for a man that can only spell a word one way.
-Mark Twain
 
D

David A. Black

Hi --

  foo.methods[:new, :protected]   # if you need combination

This line's got me thinking... How does one define a class [] constructor? For
example Hash can be use like this:

Hash[:a=>1,:b=>2 ]

class C
def C.[](...)
...
end
end
And then I start to wonder why we can't just use the class name like a method?

Hash:)a=>1, :b=>2)

You can define such methods; for example, there's Integer. A number
of people (including me :) aren't big fans of method names that begin
with uppercase letters, but it can be done.


David
 

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,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top