Pervasive Methods

Chris C. wrote:

and make them overriable, and also allow access to the object through
the Pervasive. Problem here though, when writing a library we won’t
know that someone overrode a method somewhere else in the chain, so we
are stuck using the Pervasive a lot anyway. Why this isn’t a problem
now you might ask? Because we don’t have the Pervasive, so people are
less willing to override those methods. We still won’t have a good
looking #send that calls private methds. Well, we will, but it needs
a name. I am willing to write up the RCR on this one.

An RCR for Pervasives? If so I’d like to add a note…

Using Pervasives means an object won’t be able to trick you. Is that
good? If my class is a proxy then shouldn’t it be able to trick you?
I’m not sure about this, maybe that’s just foolish when it comes to
fundamental properties like class and id.

Also, if we have both pervasive methods PLUS the methods we presently
use, then we have the issue of inconsistancy. My object says it’s a
“PeterPiper” but Pervasives say it’s a “PickedPepper”. Obviously
Pervasives is right, so what’s the point of ever using the normal
method? Even if you know your own class in and out, you never know when
some one might come along and want to extend it. B/c of this Pervasives
would deservidely become common usage, so there should be a concise
syntax for it. “Pervasives.send obj, message” IMO is too long.

T.

On Fri, 5 Jan 2007, Trans wrote:

“Pervasives.send obj, message” IMO is too long.

P = Pervasives

P.send obj, message

??

-a

On 1/4/07, [email protected] [email protected] wrote:

On Fri, 5 Jan 2007, Trans wrote:

“Pervasives.send obj, message” IMO is too long.

P = Pervasives

P.send obj, message

??

Why not get rid of Pervasives / P altogether and simply have some new
keywords in the parser?

send obj message
id obj

Blessings,
TwP

[email protected] wrote:

On Fri, 5 Jan 2007, Trans wrote:

“Pervasives.send obj, message” IMO is too long.

P = Pervasives

P.send obj, message

??

Well, that’s shorter, yes. Though I was thinking more along the lines
of something unique.

Alternate to dot:

obj$send message

Or maybe

obj!send message

Global method:

$send obj, message

Or maybe reuse $. (and make input line number something else):

$.send obj, message

T.

On Fri, 5 Jan 2007, Trans wrote:

Or maybe

obj!send message

that’s pretty good. i was leaning towards a module so we could just try
to
write it as an extension now though…

-a

On Sat, 6 Jan 2007, Trans wrote:

Oh, sorry ara. I was actually talking about the arrow.

The arrow is more ugly!? in that case try writting some heavy meta-code
using Pervasives and __(obj) and let me know how it goes :wink: [trust me
I’ve done it].

it’s done!

http://groups-beta.google.com/group/comp.lang.ruby/browse_frm/thread/cdd56441a6005a36/e6b4110167555781?hl=en#e6b4110167555781

test it and let me know

-a

On 1/5/07, Gregory B. [email protected] wrote:

A backwards send arrow :wink:

obj ← “message”

Oh jeez, should have read the full thread. Guess this bad idea
already came up :slight_smile:

On Fri, 5 Jan 2007, Tim P. wrote:

Why not get rid of Pervasives / P altogether and simply have some new
keywords in the parser?

shorter would be better alright.

send obj message
id obj

it has to hang of another object otherwise

class C
def foo
send :inspect # keyword or method?
end
end

still. shorter is good. maybe something like

__( obj ).send message

where ‘__’ returns a proxy for Pervasives?

-a

Gregory B. wrote:

don’t think it’s possible to do presently, but I think it’s about as
ugly as everything else suggested, no more, no less.

but it’s possible NOW. see the latest annouce on the list!

Oh, sorry ara. I was actually talking about the arrow.

The arrow is more ugly!? in that case try writting some heavy meta-code
using Pervasives and __(obj) and let me know how it goes :wink: [trust me
I’ve done it].

T.

Trans wrote:

obj = “hello”
obj!class #=> String

obj = 1
obj!send + 2 #=> 3

Oops… that’s supposed to be:

obj = “hello”
class!obj #=> String

obj = 1
send!obj + 2 #=> 3

T.

On Jan 4, 2007, at 5:34 PM, [email protected] wrote:

On Fri, 5 Jan 2007, Trans wrote:

Or maybe
obj!send message

that’s pretty good. i was leaning towards a module so we could
just try to
write it as an extension now though…

This has been an interesting discussion but I think several related
issues have been bundled together, perhaps unnecessarily:

  1. literal vs. dynamic method names

recv.method # method is explicitly named
recv.send x # method is dynamically named

  1. public vs. private

recv.private_method # error
recv.send :private_method # 1.8 no error, 1.9 error
recv.funcall :private_method # 1.9 no error
recv.__send! :private_method # 1.9 no error

  1. name clashes and meta programming

recv.send # is this Object#send or something else?
recv.send # probably Object#send but no guarantee
recv.__send # same as send? or as send? or Object#send?
recv.__send! # ???
recv.class # is this Object#class? is this for recv
# or for an object proxied by recv?
recv.object_id # was this overridden? what about proxies?

I wonder if 1 & 2 might be better addressed via syntax. Something like:

recv.m # standard dispatch with literal method name
recv <- :m # standard dispatch with dynamic method name
recv <- :m2, a1 # dynamic method name with arguments
recv <-(:m2, a1) { #block} # parens needed with blocks

recv <<- :stuck_out_tongue: # standard dispatch with access to private method :stuck_out_tongue:

Currently a standard method (Object#send) is required to access a
dynamically
named method and that forces the dispatch semantics of the
Object#send mechanism
to become mingled with the dispatch of the message itself. That
isn’t the case
with the standard ‘dot’ dispatch and I think it complicates the
situation
quite a bit. By using different syntax for dispatch to dynamically
named methods
there is no need to worry about Object#send itself being overridden.
The syntax
I suggested above (<- and <<-) is not special, just a way to
illustrate the idea.

That still leaves the problem of name clashes and unanticipated
redefinitions for
things like #class, #object_id, and so on. Could this be handled by
providing
a way to override the normal method lookup process?

(recv, BasicObject).class
(recv, BasicObject).object_id

Again, the syntax is just a suggestion, but the idea is to force
Ruby’s method lookup
process to begin its search with a particular class, bypassing the
normal order of
lookups. The two ideas can be combined:

(recv, BasicObject) <- :class

BasicObject could be frozen so that its methods can’t be redefined/
undefined.

Regardless of my particular suggestions I think it is helpful to view
the issues (1,2,3)
separately rather than as a larger indivisible problem.

Gary W.

On Sat, 6 Jan 2007, Gregory B. wrote:

don’t think it’s possible to do presently, but I think it’s about as
ugly as everything else suggested, no more, no less.

but it’s possible NOW. see the latest annouce on the list!

Oh, sorry ara. I was actually talking about the arrow.

ah. well, they are both ugly, but i chose the one that’s possible and
ugly
:wink:

cheers.

-a

[email protected] wrote:

probably
shouldn’t be overloaded (e.g. Object#send) to access those different
types
of dispatches (for the same reasons that dot itself isn’t a method based
operator)

And I agree. And I think the syntax you have suggested is pretty close.

recv.method arg1 # literal method
recv OP1 :name, arg1 # dynamic method
recv OP2 Klass, :name, arg1 # dynamic with modified method lookup

Hmm… because the method will always be a string or symbol, a class or
module could be distinguished, so looking at your template I now see
that it’s possible for OP1 == OP2:

obj -> Base, :name, *args

And I wonder if the Base form could grant access to private space too?
The Base form is pretty meta-hackery in itself so I think that would be
okay. Then we would’t need an “OP3” for private access. Just do:

obj -> (obj ~> :class), :name, *args

where ~> is pervasive send.

I think different types of dispatch operators would end up having
clearer
semantics than ‘magic’ methods (like BasicObject#send). I don’t have
any
great ideas about the actual syntax though. I don’t like the
Pervasive class
idea (nor the name itself even if the idea were to catch on).

I know the mnemonic isn’t great, but ‘->’ really is common as a
dispatch op. Anyone who’s done their share of Perl or PHP coding is
going to feel right at home with it. And I think the rest of us can
grow accustomed. So maybe give it a chance? B/c if so, I think this is
looking pretty damn nice!

T.

On Fri, 5 Jan 2007, Tim P. wrote:

end

ruby a.rb
keyword 1
keyword 2

That’s the beauty of keywords – the parser is going to intercept them
and invoke the appropriate function via the lexer. Unless I did not
properly define my “if” method there.

my mistake. still, it’d be cool to see if we could hack into the
current
ruby… though i’ve no idea if that’s possible attm.

-a

I really think adding a new keyword, or way of calling methods is a
bad idea, and a big code smell. Having the pervasive show something
is different than the class might want you to think is good. How many
times have you been confused by some of Rails’ proxy arrays, I know I
have been fooled many times, using the Pervasive in metaprogramming
allows us to see what the class ACTUALLY is.

On Jan 5, 2007, at 3:56 PM, Trans wrote:

The operator you suggest however would probably have to be flipped to
avoid ambiguity with Symbol#@-. Eg. recv < -:class (I know rare. but
possible).

The mnemonics are all wrong if you flip it:

obj <- message # sending the message to the object
obj -> message # sending the object to the message?

You have to think of <- as a two character operator. Of course
the parser would also have to think of it that way. There would have to
be some white space to have it parse as ‘<’ and ‘-’ separately. My only
point is that it can be parsed, but a syntax that was a bit more
stable with respect to white space would certainly be better.

As for the class search idea, that can be done easily enough with:

recv.as(BasicObject) -> :class

This introduces the same problem I pointed out with respect to the
semantics of #send but this time with #as. In fact it is worse because
you’ve got normal method call syntax but completely different semantics
since
recv.as(BasicObject)
will parse as an expression to be evaluated as the lhs of the ‘->’
operator.
What kind of object would #as return and how would the -> operator know
about the receiver?

To outline, this would give ruby a complete set of dispatch operators:

. literal
<- dynamic
<<- functional (dynamic)
<~ pervasive (dynamic)

Having a syntax for starting method lookup in a particular class also
gives you a way to call a method that has been redefined without having
to play games with aliases:

class A; def m; end; end
class B < A; def m; end; end

class C
def example
self.m # calls B#m
(self, A) <- :m # calls A#m (kind of ugly syntax though)
end
end

Gary W.

On Jan 5, 2007, at 6:06 PM, Trans wrote:

Matz’s no look-ahead rule for the parser. Is that true? And if it is,
have you any other suggestion for it?

I don’t know quite enough about the grammar to say if that syntax works
or not. I suspect that it isn’t any more of a problem than the current
parallel assignment syntax:

(a,b) = :foo, :bar

The only thing different is the operator. But I really don’t like that
syntax myself. My main point is that there are different sorts of
‘dispatches’
you might want to have available and that the standard method syntax
probably
shouldn’t be overloaded (e.g. Object#send) to access those different
types
of dispatches (for the same reasons that dot itself isn’t a method based
operator)

recv.method arg1 # literal method
recv OP1 :name, arg1 # dynamic method
recv OP2 Klass, :name, arg1 # dynamic with modified method lookup

I’m not sure what OP1 or OP2 might be that would look reasonable,
have some
sort of reasonable mnemonic, and also not screw up the grammar. Maybe:

recv.method(arg1) # literal method
recv.(:method, arg1) # dynamic (mnemonic: * is a wild card?)
recv.**(Klass, :method, arg1) # dynamic with modified lookup
recv.
!(:method, arg1) # private also
recv.**!(Klass, :method, arg1) # modified and private

I think different types of dispatch operators would end up having
clearer
semantics than ‘magic’ methods (like BasicObject#send). I don’t have
any
great ideas about the actual syntax though. I don’t like the
Pervasive class
idea (nor the name itself even if the idea were to catch on).

Gary W.

On 1/5/07, Trans [email protected] wrote:

but it’s possible NOW. see the latest annouce on the list!

Oh, sorry ara. I was actually talking about the arrow.

The arrow is more ugly!? in that case try writting some heavy meta-code
using Pervasives and __(obj) and let me know how it goes :wink: [trust me
I’ve done it].

No. I see the arrow to be equivalent to __(obj) and prettier than an
explicit Pervasive object.
I suggested the arrow since it was the best I could come up with, but
I should have read the thread before to see it was already suggested.
I would have been kinder then, perhaps, since I thought I was making
fun of myself :slight_smile:

On 1/4/07, [email protected] [email protected] wrote:

still. shorter is good. maybe something like

__( obj ).send message

This is a really bad idea, but I might as well put it out there. I
don’t think it’s possible to do presently, but I think it’s about as
ugly as everything else suggested, no more, no less.

A backwards send arrow :wink:

obj ← “message”

[email protected] wrote:

On Fri, 5 Jan 2007, Trans wrote:

Or maybe

obj!send message

that’s pretty good. i was leaning towards a module so we could just try to
write it as an extension now though…

irb(main):003:0> class Object
irb(main):004:1> def p(obj=(not_obj=true;nil))
irb(main):005:2> return Pervasives if not_obj
irb(main):006:2> super obj
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> module Pervasives
irb(main):010:1> module_function
irb(main):011:1> def send(obj, *args, &blk)
irb(main):012:2> obj.send(*args,&blk)
irb(main):013:2> end
irb(main):014:1> end
=> nil
irb(main):015:0> p “2”
“2”
=> nil
irb(main):016:0> p.send(“2”,:class)
=> String
irb(main):017:0> p.send “2”, :class
=> String

Then go “p p” :wink:

T.