Yukihiro M. schrieb:
|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?
FWIW, I also like “send!” much more than “funcall”. The only thing
bothering me: for classes with their own “send” method, “send” and
“send!” wouldn’t be related to each other.
Therefore I prefer “invoke_method” and “invoke_method!”. I would even
deprecate “send” if it wouldn’t break so much code.
Regards,
Pit
Yukihiro M. wrote:
#method_missing is and will be called when you invoke private methods
with the receiver specified.
Great! Thank you…
I have come up with the following implementation as a more flexible
solution to BlankSlate. I called it InterfaceFilter for lack of a
better name. I see one prbolem though. It cannot react dynmically when
a new method is added to an ancestor. While, it would make sense if
#method_added triggered the same callback in effected sublasses, I
suppose that’s too much overhead. Still, is their anyway to achieve
dynamic behavior here?
T.
module InterfaceFilter
ESSENTIAL = [ ‘funcall’, ‘send’, ‘object_id’, ‘object_class’
‘equal?’, ‘==’, ‘dup’, ‘clone’ ]
SECONDARY = [ ‘class’, ‘respond_to?’, ‘inspect’, ‘hash’ ]
OPERATOR = [ /^\W$/ ]
SHADOW = [ /^__/ ]
QUERY = [ /?$/ ]
INSTANCE = [ /^instance_/ ]
DEFAULT = ESSENTIAL | SECONDARY | SHADOW | OPERATOR | QUERY
def self.included( base )
base.const_set( ‘InterfaceFilter’, self )
end
def self.
cls = self.dup
cls.preserve_features( patterns, public_instance_methods(true) )
cls
end
def self.preserve_features( patterns, methods=nil )
patterns.flatten!
methods ||= Kernel.public_instance_methods
methods.each do |m|
case m
when *patterns
public m
else
private m
end
end
end
preserve_features( DEFAULT )
end
#= begin test
class X
include InterfaceFilter[ InterfaceFilter::ESSENTIAL ]
end
x = X.new
p X.ancestors
p x.class
p x.instance_variables
#=end
Hi –
On Tue, 4 Jul 2006, 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.
I’m not clear on what you mean. Don’t these all have receivers?
I would still say that “send” is a better fit for explicitly sending a
message to an object. With ‘call’ and ‘invoke’ you’re saying to the
object: here’s a message and here’s what you should do with it. I
think the caller should send the message – even a meta-message, as
with send – and the object should decide what’s going to happen.
David
Daniel DeLorme wrote:
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.
I’d prefer having the functionality built-in as well. It might happen in
the next few years from what I understand.
[email protected] wrote:
I have come up with the following implementation as a more flexible
solution to BlankSlate. I called it InterfaceFilter
Hmm… I may again have overshot the solution. It’s easy enough to
privatize methods as needed, one doesn’t need a intervening module to
do that. So I’ll push this back to a BlankSlate like class.
Also, I see now where the limitation on the dynamic behavior actually
lies:
class X
private :q
end
NameError: undefined method q' for class
X’
from (irb):2:in `private’
from (irb):2
from :0
As with my method annotation system, one might wish to predefine a
characeristic, in this case the visibility of a potential method. In
this way it could even be reused. Eg.
module Shh
private :s
end
class S
include Shh
def s
“s”
end
end
S.new.s #=> Error private method
Possible?
T.
On Tue, 4 Jul 2006, Florian G. wrote:
Daniel DeLorme wrote:
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.
I’d prefer having the functionality built-in as well. It might happen in the
next few years from what I understand.
any idea of the limitations of Binding.of_caller?
-a
On Jul 4, 2006, at 10:52 AM, [email protected] wrote:
happen in the next few years from what I understand.
any idea of the limitations of Binding.of_caller?
Well you can’t use a trace function when you are using binding of
caller, it has to be the last bit of code in a method that uses it,
and it uses continuations (which are slow).
Hi,
In message “Re: About 1.9 #method feature.”
on Tue, 4 Jul 2006 21:26:00 +0900, [email protected] writes:
|> 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.
|
|I’m not clear on what you mean. Don’t these all have receivers?
They have receivers. But they are not “specified” for functional
styles.
matz.
[email protected] wrote:
any idea of the limitations of Binding.of_caller?
It depends on a bug in Ruby (but that can be fixed as soon as that bug
is fixed) and will only work 100% correctly if you are using it in a
method that is called in the same context as its caller. For example
breakpoint() is OK, but Breakpoint.breakpoint() will not give you the
correct instance variables.
I don’t think it is too slow. Not being able to restore previous trace
funcs is another downside, however.
Perhaps it is time to write a C extension for this after all?
Hi,
In message “Re: About 1.9 #method feature.”
on Wed, 5 Jul 2006 03:53:25 +0900, [email protected] writes:
|> They have receivers. But they are not “specified” for functional
|> styles.
|
|Can you show me an example? I’m still not understanding. I’m
|thinking of:
|
| obj.funcall(:meth)
|
|but maybe there’s a different/new syntax for funcall? Is it now a
|top-level method?
Ah, maybe I didn’t express myself clear.
obj.send(:foo, args)
does work like
obj.foo(args)
and
obj.funcall(:foo, args)
works like
foo(args)
I mean this “foo(args)” when I said “receiver not specified”.
matz.
On Jul 4, 2006, at 2:53 PM, [email protected] wrote:
David
meth is the “top level” method.
e.g.:
class A
def initialize
jump_up_and_down( ) # look, I’m calling a “function” (No
explicit receiver)
end
private
def jump_up_and_down( )
…
end
end
That’s why top level declared methods are private. It’s to
distinguish “function” methods from method methods. Hence the name
“funcall” (call a “function”)
Hi –
On Wed, 5 Jul 2006, Logan C. wrote:
top-level method?
jump_up_and_down( ) # look, I’m calling a “function” (No explicit
“function”)
I don’t like it. It seems wrong to go through a non-functional style
to tell an object to call something internally in a functional style,
when in fact the “style” only referred to the lexical and
typographical convention in the first place.
Besides, if jump_up_and_down were not private, it could still be
called with an implicit receiver in A#initialize. I don’t think that
puts it in a different category of method.
It also seems that the notion of a function (or “function method”) is
emerging in Ruby as a kind of side effect of the new method names. I
don’t see anything here that can’t be handled thoroughly without this
notion.
David
Hi –
On Wed, 5 Jul 2006, Yukihiro M. wrote:
|I’m not clear on what you mean. Don’t these all have receivers?
They have receivers. But they are not “specified” for functional
styles.
Can you show me an example? I’m still not understanding. I’m
thinking of:
obj.funcall(:meth)
but maybe there’s a different/new syntax for funcall? Is it now a
top-level method?
David
On 7/4/06, Yukihiro M. [email protected] wrote:
Ah, maybe I didn’t express myself clear.
obj.send(:foo, args)
does work like
obj.foo(args)
and
obj.funcall(:foo, args)
works like
foo(args)
So:
class Foo
def foo(*args)
end
private :foo
def bar(*args)
end
end
obj = Foo.new
obj.foo(5) # Throws an error, just as now.
obj.send(:foo, 5) # ???
obj.funcall(:foo, 5) # ???
Will #funcall be the way that I can circumvent private?
-austin
On Jul 4, 2006, at 3:21 PM, [email protected] wrote:
obj.funcall(:meth)
jump_up_and_down( ) # look, I’m calling a “function” (No
“funcall” (call a “function”)
It also seems that the notion of a function (or “function method”) is
emerging in Ruby as a kind of side effect of the new method names. I
don’t see anything here that can’t be handled thoroughly without this
notion.
David
Well this is basically what matz. has said before, I just put my own
words to it. The function method concept didn’t come from the method
name, matz. named the method #funcall based on his function method
concept.
Hi,
In message “Re: About 1.9 #method feature.”
on Wed, 5 Jul 2006 04:23:51 +0900, “Austin Z.”
[email protected] writes:
|Will #funcall be the way that I can circumvent private?
obj.foo(5) # Throws an error, just as now.
obj.send(:foo, 5) # Throws an error, it’s private.
obj.funcall(:foo, 5) # Success. funcall can call private.
On Wed, 5 Jul 2006, Yukihiro M. wrote:
Hi,
In message “Re: About 1.9 #method feature.”
on Wed, 5 Jul 2006 04:23:51 +0900, “Austin Z.” [email protected] writes:
|Will #funcall be the way that I can circumvent private?
obj.foo(5) # Throws an error, just as now.
obj.send(:foo, 5) # Throws an error, it’s private.
obj.funcall(:foo, 5) # Success. funcall can call private.
what improvement does that give over
obj.instance_eval{ send :foo, 5 }
??
i mean, what’s the purpose of a public method which can call private
methods?
-a
On 7/4/06, Yukihiro M. [email protected] wrote:
Me:
Will #funcall be the way that I can circumvent private?
obj.foo(5) # Throws an error, just as now.
obj.send(:foo, 5) # Throws an error, it’s private.
obj.funcall(:foo, 5) # Success. funcall can call private.
Okay. Next: what will the non-overridable versions of these methods be?
Will I have to do
Object.method(:send).bind(obj).call(:foo, 5)
or will there be an equivalent to #send still? Will #object_id be
overridable? I would prefer to have a simple, clear way that cannot be
overridden to get at these values which, for readability purposes, can
or should be overridden. (#send is a particularly nasty example, since
Mail#send would be appropriate. 
I am not a fan of #funcall – yes, it’s called without an explicit
receiver, but it is called with an implicit receiver. Given that this
is the case, I think that the #send/#send! dichotomy is not appropriate.
Trans had a suggestion that I’ve chewed on for a while and think might
be worthwhile considering for this sort of thing. Perhaps we need these
sorts of methods to be external to classes, say Meta:
Meta.object_id(obj)
Meta.send(obj, :foo, 5) # fails on private
Meta.implicit_send(obj, :foo, 5) # succeeds on private
I’m not sure. I do think that #implicit_send is better than #funcall,
and maybe #explicit_send is better than #send.
-austin
Florian G. wrote:
I don’t think it is too slow. Not being able to restore previous trace
funcs is another downside, however.
Perhaps it is time to write a C extension for this after all?
I was never quite sure why it wasn’t already. After all you can get the
binding of the caller if you pass a block,even an empty one.
def x( &blk )
Kernel.eval( "self", blk.binding )
end
T.
[email protected] wrote:
Hmm… I may again have overshot the solution. It’s easy enough to
privatize methods as needed, one doesn’t need a intervening module to
do that. So I’ll push this back to a BlankSlate like class.
I have to be honest. I feel like a complete schmuck here. Coming to the
full relaization that method_missing catches public calls to private
methods means that BlankSlate is a lot of fuse over a very little --a
handful of methods, whch could just as easily be declared private. If
only I had realized sooner! Oh, well. Live and learn. Anyway, throwing
out BlankSlate sure makes things simpler. Something I always like.
One thing though. Like #id before it, many times I find myself wanting
to use an attribute called ‘class’ but that gets in the way of the
Kernel method. Maybe #object_class, like #object_id,would actually be
better?
Thanks for helping me see the light.
T.