send operator: proof of concept implementation

T

Trans

Put together a proof of concept of Gary Wright's idea of using an
operator for send instead of a method. This also incorporates an
implementation of Ara's Pervasives. There are a couple caveats to this
implementation however that would have to be handled in any production
version.

1) It uses >> rather then ->, for obvious reasons. So as it is, it will
not work with a few classes that already use >> (unless they are
redefined).

2) You have to pass an array, since an operator normally can't handle
more that one arg. This also means unfortunately that blocks can't be
passed.

3) It doesn't provide a "pervasive send" operator.

Usage:

# send equivalent to '.'
obj >> [:method, *args]

# send as (binds to method in parent class/module)
obj >> [Ancestor, :method, *args]

The second form can also be used to bypass privacy.

obj >> [(obj>>:class), :method, *args]

Albeit this will bypass singletons (aside from this it would be nice to
have method that returns the singleton if it exists, but the regular
class otherwise).

---

module Kernel

module Pervasives
METHODS = {}
Kernel.instance_methods.each do |m|
METHODS[m] = Kernel.instance_method(m)
end
METHODS.each do |s,m|
define_method s do |o,*a|
m.bind(o).call(*a)
end
module_function s
end
end
Pervasives.freeze(Pervasives)

def >>(a)
a = [a].flatten
case a[0] when Module, Class
c, m, *a = *a
c.instance_method(m).bind(self).call(*a)
else
if respond_to?(a[0])
Pervasives.send(self,*a)
elsif respond_to?:)method_missing)
method_missing(*a)
else
raise NoMethodError, "private method called for #{self}"
end

end
end

end


#=begin test

require 'test/unit'

class TestSendOP < Test::Unit::TestCase

class C
def a; "c"; end
end

class X < C
def send; "send"; end
def a; "a"; end
private
def b; "b"; end
end

def setup
@x = X.new
end

def test_send
assert_equal( "send", @x.send )
end

def test_normal
assert_equal( "a", @x >> [:a] )
end

def test_as_C
assert_equal( "c", @x >> [C,:a] )
end

def test_singleton
assert_equal( "a", @x >> [(class<<@x;self;end),:a] )
end

def test_singleton_bypass_private
assert_equal( "b", @x >> [(class<<@x;self;end),:b] )
end

def test_private
assert_raises(NoMethodError){ @x >> [:b] }
end

end

#=end
 
G

gwtmp01

Put together a proof of concept of Gary Wright's idea of using an
operator for send instead of a method. This also incorporates an
implementation of Ara's Pervasives. There are a couple caveats to this
implementation however that would have to be handled in any production
version.

Interesting. Just to clarify: If my idea is worth anything it can't
really be implemented via a redefine-able operator. That would just
change
the area of concern from #send being redefined to #operator being
redefined.
I realize that Trans is basically just experimenting with syntax at this
point.
1) It uses >> rather then ->, for obvious reasons. So as it is, it
will
not work with a few classes that already use >> (unless they are
redefined).

Well, I would still argue that << would be better than >> for mnemonic
reasons but I understand that a lot more classes have << already
defined.
3) It doesn't provide a "pervasive send" operator.

Well, as long as folks aren't redefining methods in BasicObject you
*almost*
have a "pervasive send" operator:

obj >> [BasicObject, :eek:bject_id]

I think there is a strong argument to be made that BasicObject should be
frozen. You can override methods there via inheritance but I don't
think
BasicObject itself should be modified.

Gary Wright
 
G

Gregory Brown

Interesting. Just to clarify: If my idea is worth anything it can't
really be implemented via a redefine-able operator. That would just
change
the area of concern from #send being redefined to #operator being
redefined.
I realize that Trans is basically just experimenting with syntax at this
point.


Well, I would still argue that << would be better than >> for mnemonic
reasons but I understand that a lot more classes have << already
defined.

Yeah, if we were to go the arrow route, you'd probably want

obj <- message and want <- to be something you can't override.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top