About 1.9 #__method__ feature

Hi –

On Tue, 4 Jul 2006, James Edward G. II wrote:

On Jul 3, 2006, at 10:59 AM, [email protected] wrote:

I haven’t noticed invoke_functional_method. I admit I’m still unclear
on the (new?) use of the notion of ‘function’ in addition to
‘method’… How do you characterize a functional method, in this
context?

Well, a private method is not suppose to be invoked externally, so it’s not
really a “method call.” That’s my best guess at the reasoning…

I can see that point, but I’m not sure how it leads to the concept of
a functional method. It seems like all of these permutations could be
built on the basic message-sending paradigm, where the act of the
caller (sending a message) is separate from the act of the object
(deciding what to do in response to the message).

To me, “funcall” and anything referring directly to method-invocation
do a short-circuiting of that paradigm.

By contrast, consider:

obj.method(:m).call

In this case, the caller has to go through a separate step – which I
think is good. I wouldn’t want to see that turned into:

obj.method_call(:m)

David

James Edward G. II wrote:

Yeah, I’m with David in that I liked send/send!, so this seems a
natural extension to me.

Same here.

Let’s pester Matz until he gives in.

:slight_smile:


James B.

“A language that doesn’t affect the way you think about programming is
not worth knowing.”

  • A. Perlis

On Tue, Jul 04, 2006 at 12:48:18AM +0900, [email protected] wrote:
[…]
} maybe a meta-method to return all the info:
}
} #
} # an array of objects representing call record
} #
} where = where
}
} #
} # the first record is the call we’re in
} #
} p where[0].file #=> same as FILE
} p where[0].method #=> same as method
} p where[0].line #=> same as LINE
} p where[0].binding #=> same as binding
}
} #
} # but this one reaches up like binding_of_caller
} #
} p where[1].file #=> same as FILE
} p where[1].method #=> same as method
} p where[1].line #=> same as LINE
} p where[1].binding #=> same as binding
}
} #
} # and even further!
} #
} p where[2].file #=> same as FILE
} p where[2].method #=> same as method
} p where[2].line #=> same as LINE
} p where[2].binding #=> same as binding
}
}
} basically i’m proposing a ‘caller’ like interface which returns an
array
} of objects having all the ‘location’ information, including
} scope/binding. this could be amazingly useful.

+1

I like that!

} regards.
} -a
–Greg

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 01:10:40 +0900, [email protected] writes:

|What is you take on this?

I am sorry but I am not sure what you’re asking here.

I have considered separating public and private method name spaces
several times, but always failed to make it well designed.

						matz.

On Jul 3, 2006, at 10:48 AM, [email protected] wrote:

basically i’m proposing a ‘caller’ like interface which returns an
array of
objects having all the ‘location’ information, including scope/
binding. this
could be amazingly useful.

I think this is a sign of how broken caller() is. Ara’s version
seems much more Rubyish to me.

James Edward G. II

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 00:48:18 +0900, [email protected] writes:

|# an array of objects representing call record
|#
| where = where

I think there must be better name than where for this
functionality. I think where would give us more simple value like
mere string or a number, by association with FILE etc.

						matz.

On 7/3/06, Yukihiro M. [email protected] wrote:

functionality. I think where would give us more simple value like
mere string or a number, by association with FILE etc.

How about context ?

Yukihiro M. wrote:

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 01:10:40 +0900, [email protected] writes:

|What is you take on this?

I am sorry but I am not sure what you’re asking here.

No problem. I will try to paint better picture. I have variant of
OpenStruct called OpenObject:

class OpenObject < BasicObject #(this is my BasicObject like
BlankSlate)

Using BasicObject as parent removes (almost) all kernel methods which
ensures no name clashes when using the OpenObject. Problem is sometimes
those removed methods are needed. So the important ones are available
by shadow methods, like send even though #send is removed. Problem
is A) how many and which kernel methods should be shadowed; all of
them? and worse B) it means users have to be aware when a subclass of
BasicObject might be used and call the LCD, ie. shadow methods instead
of regular methods.

I came up with one idea that fixes A. using #self, eg.

o = OpenObject.new
o.class #=> nil
o.self.class #=> OpenObject

But it does not solve worse problem of B. Separate public vs. private
methods would solve that though since kernel methods are generally
private.

I have considered separating public and private method name spaces
several times, but always failed to make it well designed.

What were the sticking points? I spent some time considering this and
arrived at a conception of layers, almost like subclassing, eg
MyClass:Public < MyClass:Private.

T.

Wilson B. wrote:

On 7/3/06, Yukihiro M. [email protected] wrote:
How about context ?

$FRAME()

or

$FRAME[]

Maybe better for LINE and FILE too.

if $0 == $FILE

Bye-bye shadows! :slight_smile:

T.

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 02:07:30 +0900, [email protected] writes:

|No problem. I will try to paint better picture. I have variant of
|OpenStruct called OpenObject:
|
| class OpenObject < BasicObject #(this is my BasicObject like
|BlankSlate)
| …
|
|Using BasicObject as parent removes (almost) all kernel methods which
|ensures no name clashes when using the OpenObject. Problem is sometimes
|those removed methods are needed. So the important ones are available
|by shadow methods, like send even though #send is removed. Problem
|is A) how many and which kernel methods should be shadowed; all of
|them? and worse B) it means users have to be aware when a subclass of
|BasicObject might be used and call the LCD, ie. shadow methods instead
|of regular methods.

I don’t know what you expect for BasicObject and OpenObject.
BasicObject is a BasicObject what it is. Could you describe what you
want and what you expect first please? BasicObject may not be the
answer for your problem. If it’s not the right answer, tweaking it to
adopt your requirement might not be a good idea.

|I came up with one idea that fixes A. using #self, eg.
|
| o = OpenObject.new
| o.class #=> nil
| o.self.class #=> OpenObject

What does this self do?

|What were the sticking points?

Separating it would break Ruby’s object model. It would make it much
more complex at least, far more complex than I can bear.

|I spent some time considering this and
|arrived at a conception of layers, almost like subclassing, eg
|MyClass:Public < MyClass:Private.

? Sorry, I don’t get it.

						matz.

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 03:11:04 +0900, [email protected] writes:

|> |Using BasicObject as parent removes (almost) all kernel methods which
|> |ensures no name clashes when using the OpenObject. Problem is sometimes
|> |those removed methods are needed. So the important ones are available
|> |by shadow methods, like send even though #send is removed. Problem
|> |is A) how many and which kernel methods should be shadowed; all of
|> |them? and worse B) it means users have to be aware when a subclass of
|> |BasicObject might be used and call the LCD, ie. shadow methods instead
|> |of regular methods.
|>
|> I don’t know what you expect for BasicObject and OpenObject.
|> BasicObject is a BasicObject what it is. Could you describe what you
|> want and what you expect first please? BasicObject may not be the
|> answer for your problem. If it’s not the right answer, tweaking it to
|> adopt your requirement might not be a good idea.
|
|OpenObject is just like OpenStruct, but it is faster and removes
|methods that would get in thte way using BasicObject, for example
|#class.

Hmm, and you cannot use private methods in the subclass of OpenObject.
What should we do? Maybe you can define your own version of
BlankSlate that makes every required method into private, instead of
undef’ing it.

I just revisited separating two namespaces, but it would break 80-90%
of Ruby programs. Even though I accept some code breakage in 1.9,
it’s just too much.

						matz.

Yukihiro M. wrote:

|> |them? and worse B) it means users have to be aware when a subclass of
|methods that would get in thte way using BasicObject, for example
|#class.

Hmm, and you cannot use private methods in the subclass of OpenObject.
What should we do? Maybe you can define your own version of
BlankSlate that makes every required method into private, instead of
undef’ing it.

Yes!!! I had totally forgotten about that little trick with
method_missing catching public calls to otherwise private methods. Can
I always depend on Ruby working that way? If so I think it’s all good.

I just revisited separating two namespaces, but it would break 80-90%
of Ruby programs. Even though I accept some code breakage in 1.9,
it’s just too much.

Yes, too much. And too much complexity --you are right. Like a child
learning, my initial solutions tend to overreach. It’s not that we need
to totally separate public and private methods, rather we need only be
able to act according to which is invoked. The method_missing trick
should work perfectly.

Thank you Matz! I’m working on this tonight!

T.

Yukihiro M. wrote:

| …
I don’t know what you expect for BasicObject and OpenObject.
BasicObject is a BasicObject what it is. Could you describe what you
want and what you expect first please? BasicObject may not be the
answer for your problem. If it’s not the right answer, tweaking it to
adopt your requirement might not be a good idea.

OpenObject is just like OpenStruct, but it is faster and removes
methods that would get in thte way using BasicObject, for example
#class. More detailed example:

require ‘facet/openobject’
require ‘ostruct’
oo = OpenObject.new
os = OpenStruct.new
oo.class = “foo” #=> “foo”
os.class = “foo” #=> “foo”
oo.class #=> “foo”
os.class #=> “OpenStruct”

Also BasicObject can be useful for any class that uses method_missing
since it removes kernel methods that would not otherwise be missing.

What does this self do?

class BasicObject

The Self class allows one to get access the hidden Object/Kernel

methods.

It is essentially a specialized Functor which binds an

Object/Kernel

method to the current object for the current call.

class Self < self
def initialize(obj, as=nil)
@obj = obj
@as = as || ::Object
end
def method_missing(meth, *args, &blk)
@as.instance_method(meth).bind(@obj).call(*args, &blk)
end
end

Returns the Self functor class, which can then be used to

call Kernel/Object methods on the current object.

def self
@self ||= Self.new( self )
end

This method is like #self, but allows any ancestor

to act on behalf of self, not just Object.

def as( ancestor )
Self.new( self, ancestor )
end

|What were the sticking points?

Separating it would break Ruby’s object model. It would make it much
more complex at least, far more complex than I can bear.

|I spent some time considering this and
|arrived at a conception of layers, almost like subclassing, eg
|MyClass:Public < MyClass:Private.

? Sorry, I don’t get it.

Acutally I have that backward, sorry. MyClass:Private <
MyClass:Public.The idea beng that the public layer is like a superclass
to the private layer. Outside access is directed to the Public layer
and internal access directed to the Private layer. So clearly if a
method isn’t in the private layer it goes back to the public layer.
Private layer could even call super to access public layer. So it’s
like dividing a class inot two transparently cojoined classes.

T.

Yukihiro M. wrote:

I refer a method invocation without a receiver specified as
“functional style” because it looks like function calls in other
languages. The name “funcall” and “invoke_functional_method” reflect
that term.

What about “invoke_function”? It’s not accurate but mixing, “function”
and
“method” in the same name seems to be mixing two concepts that are
mutually
exclusive. Like saying “blackish white”.

BTW I also like the send/send! syntax (not that it seems to matter at
this point)

Daniel

Yukihiro M. wrote:

method. I just used FILE etc. for consistency with CPP.
I was under the impression that FILE was in capital letters because
it was a
constant (or rather, pseudo-constant). If method is really a method
that can
be called with self.method then by all means it should be lowercase.
But if
it’s a (pseudo)constant then it should keep the nomenclature of
constants, i.e.
uppercase letters.

Daniel

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 10:35:23 +0900, [email protected] writes:

|> Hmm, and you cannot use private methods in the subclass of OpenObject.
|> What should we do? Maybe you can define your own version of
|> BlankSlate that makes every required method into private, instead of
|> undef’ing it.
|
|Yes!!! I had totally forgotten about that little trick with
|method_missing catching public calls to otherwise private methods. Can
|I always depend on Ruby working that way? If so I think it’s all good.

#method_missing is and will be called when you invoke private methods
with the receiver specified.

						matz.

Gregory S. wrote:

On Tue, Jul 04, 2006 at 12:48:18AM +0900, [email protected] wrote:
} basically i’m proposing a ‘caller’ like interface which returns an array
} of objects having all the ‘location’ information, including
} scope/binding. this could be amazingly useful.

+1

+2, it’s brilliant! “where” is a bit non-descriptive though; “callstack”
or
something similar to “caller” might be better. I’ve somtimes wanted a
way to get
at the binding of the caller but Binding.of_caller is just too much of a
hack
and I can’t bring myself to use it. But this would be a very elegant
solution.

Daniel

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 11:46:03 +0900, Daniel DeLorme [email protected]
writes:

|What about “invoke_function”? It’s not accurate but mixing, “function” and
|“method” in the same name seems to be mixing two concepts that are mutually
|exclusive. Like saying “blackish white”.

Hmm. Let me consider.

|BTW I also like the send/send! syntax (not that it seems to matter at this point)

And invoke_method and invoke_method! as well?

						matz.

Hi,

In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 00:37:31 +0900, “Austin Z.”
[email protected] writes:

|Any chance we can get #invoke_method added to Ruby 1.8.5 so that we
|can use it instead of #send? I’ve got a lot of #send calls in
|places. It would also be useful to know which of these sorts of things
|will be used for private calls (e.g., I have code that must be able to
|call methods that are otherwise private).

I am not yet sure how much preferable adding 1.9 methods to the stable
version. Since it is mere addition, it should not cause much
problems, but increasing number of methods may be considered as being
“unstable” for the stable version. Any idea?

						matz.

On Jul 4, 2006, at 1:07 AM, Yukihiro M. wrote:

I am not yet sure how much preferable adding 1.9 methods to the stable
version. Since it is mere addition, it should not cause much
problems, but increasing number of methods may be considered as being
“unstable” for the stable version. Any idea?

  					matz.

Doesn’t this depend on how it’s added? What if we stole a page from
python’s book?

file future.rb:

module Kernel
alias invoke_method send
end

require ‘future’
obj = SomeClass.new
obj.invoke_method(…)

You could also have an empty future.rb in the stdlib of 1.9. Then
people who try to write 1.8 in a 1.9 style could use their scripts
under either version (well as far as stuff that could be backported
for “getting into the habit” purposes, like invoke_method).

Just a thought.