Forum: Ruby Pervasive Methods

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Trans (Guest)
on 2007-01-06 20:30
(Received via mailing list)
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.
unknown (Guest)
on 2007-01-06 20:30
(Received via mailing list)
On Fri, 5 Jan 2007, Trans wrote:

> "Pervasives.send obj, message" IMO is too long.

   P = Pervasives

   P.send obj, message

??

-a
Tim P. (Guest)
on 2007-01-19 17:30
(Received via mailing list)
On 1/4/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> 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
Trans (Guest)
on 2007-01-19 17:30
(Received via mailing list)
removed_email_address@domain.invalid 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.
unknown (Guest)
on 2007-01-19 17:32
(Received via mailing list)
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
unknown (Guest)
on 2007-01-19 17:32
(Received via mailing list)
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
unknown (Guest)
on 2007-09-26 00:29
(Received via mailing list)
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 ;-)  [trust me
> I've done it].

it's done!

   http://groups-beta.google.com/group/comp.lang.ruby...

test it and let me know

-a
Gregory B. (Guest)
on 2007-09-26 00:30
(Received via mailing list)
On 1/5/07, Gregory B. <removed_email_address@domain.invalid> wrote:
> A backwards send arrow ;)
>
> obj <- "message"

Oh jeez, should have read the full thread.  Guess this bad idea
already came up :)
Trans (Guest)
on 2007-09-26 00:30
(Received via mailing list)
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 ;-)  [trust me
I've done it].

T.
Trans (Guest)
on 2007-09-26 00:33
(Received via mailing list)
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.
unknown (Guest)
on 2007-09-26 00:34
(Received via mailing list)
On Jan 4, 2007, at 5:34 PM, removed_email_address@domain.invalid 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

2) 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

3) 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 <<- :p  # standard dispatch with access to private method :p

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.
Trans (Guest)
on 2007-09-26 00:34
(Received via mailing list)
removed_email_address@domain.invalid 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.
unknown (Guest)
on 2007-09-26 00:36
(Received via mailing list)
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
;-)

cheers.

-a
Chris C. (Guest)
on 2007-09-26 00:38
(Received via mailing list)
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.
unknown (Guest)
on 2007-09-26 00:39
(Received via mailing list)
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
unknown (Guest)
on 2007-09-26 00:42
(Received via mailing list)
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.
unknown (Guest)
on 2007-09-26 00:42
(Received via mailing list)
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.
Gregory B. (Guest)
on 2007-09-26 00:42
(Received via mailing list)
On 1/4/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> 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 ;)

obj <- "message"
Gregory B. (Guest)
on 2007-09-26 00:43
(Received via mailing list)
On 1/5/07, Trans <removed_email_address@domain.invalid> 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 ;-)  [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 :)
Trans (Guest)
on 2007-09-26 00:43
(Received via mailing list)
removed_email_address@domain.invalid 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...

it's backwards but... imitation of implementation:

  module Kernel

    def send! obj
      @send_f ||= Functor.new{|op,*a| obj.send(op,*a)}
    end

    def class! obj
      obj.class
    end

    def id! obj
      obj.object_id
    end

    # ...
  end

then:

  obj = "hello"
  obj!class #=> String

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

T.
Trans (Guest)
on 2007-09-26 00:45
(Received via mailing list)
removed_email_address@domain.invalid 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" ;-)

T.
Tim P. (Guest)
on 2007-09-26 00:46
(Received via mailing list)
On 1/4/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> >>
> > id obj
> >
>
> it __has__ to hang of another object otherwise
>
>    class C
>      def foo
>        send :inspect # keyword or method?
>      end
>    end
>

Hmmm ... maybe I need some enlightening, but this is what I came up with
...

> cat a.rb
def if(*a) p a end

if true then puts 'keyword 1' end

if(true)
  puts 'keyword 2'
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.

TwP
Trans (Guest)
on 2007-09-26 00:47
(Received via mailing list)
removed_email_address@domain.invalid wrote:
> 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.

I realize it's not as intuitive at first glance, but i don't think it's
"all wrong". in fact, "->" is what Perl and PHP both use rather then a
'.' so there is already plenty of precedence for it. the mnemonic
disconnect  you suggest really comes from calling the obj a "receiver".
if it'll help we can avoid that term and find a better way to "read"
this.

> > 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.

Ah, good point. Damn, and I really liked the #as method too.

> 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?

Well, that's not really an issue i don't think. It just returns a
suitable proxy. But your first point makes it rather mute in any case.

>
> 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

Agree with that, which is what I've used #as for too. Can the (self, A)
syntax you suggest really work w/o problem? I fear it might go against
Matz's  no look-ahead rule for the parser. Is that true? And if it is,
have you any other suggestion for it?

T.
Trans (Guest)
on 2007-09-26 00:47
(Received via mailing list)
Trans wrote:

> Then go "p p" ;-)

Toliet humor --I can't beleive I said that! *blush* X-)

In anycase what about uppercase:

  obj.SEND message
  obj.CLASS
  obj.ID

or maybe '::' can have some significance?

  obj::send message
  obj::class
  obj::id

T.
Gregory B. (Guest)
on 2007-09-26 00:47
(Received via mailing list)
On 1/5/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> > 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.
Trans (Guest)
on 2007-09-26 00:51
(Received via mailing list)
Chris C. wrote:
> :: is the scoping operator, so unless we can make crazy lowercase
> constants that can be run, I don't think that that's teh way to go

irb(main):001:0> obj = "string"
=> "string"
irb(main):002:0> obj::class
=> String

T.
unknown (Guest)
on 2007-09-26 00:51
(Received via mailing list)
On Sat, 6 Jan 2007, Gregory B. wrote:

> On 1/4/07, removed_email_address@domain.invalid <removed_email_address@domain.invalid> 
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.


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

-a
Chris C. (Guest)
on 2007-09-26 00:52
(Received via mailing list)
Yes, it calls methods, but just normal methods, you can't make methods
that cannot be called with ., but can with ::.  But constants cannot
be called with . (or can they?)
Trans (Guest)
on 2007-09-26 00:52
(Received via mailing list)
removed_email_address@domain.invalid wrote:
>   recv.private_method    # error
>   recv.class  # is this Object#class? is this for recv
>   recv <<- :p  # standard dispatch with access to private method :p
> named methods
>
>
> 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.

Great observations and well summarized. Thank you!

I like you're '<-' idea. I think you make a very good point about this
being a dynamic dispatch operator.  It did not dawn on me before but it
doesn't make a whole lot of sense to have overridable dyanimic dispatch
but not for literal dispatch. #send should just mean '.'  And I would
suggest that unless #send is going to control all dispatching,
including literal calls, then another operator as you suggest is the
right idea.

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

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

  recv.as(BasicObject) -> :class

Though is would be better to code #as into core. But I would like to
see a short hand for the BasicObject case. Maybe

  recv ~> :class

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

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

T.
Chris C. (Guest)
on 2007-09-26 00:52
(Received via mailing list)
:: is the scoping operator, so unless we can make crazy lowercase
constants that can be run, I don't think that that's teh way to go
unknown (Guest)
on 2007-09-26 00:53
(Received via mailing list)
On Jan 5, 2007, at 1:55 PM, removed_email_address@domain.invalid wrote:
> 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

Another thought on the syntax:

  recv.m a1
  recv._ :m, a1  # dispatch to named method
  recv.! :m, a1  # dispatch to named method (include private methods)

The mnemonic is that the underscore represents a blank method name
and the
blank is filled in by the first argument.  Just think of the sequence
"._"
and ".!" as syntax and not as the standard dot with methods "_" and "!".

Of course this means that "_" and "!" would not be valid method names
(well,
"!" is already invalid

Gary W.

P.S. Does anyone else think that language design is unnecessarily
constrained
by insisting on ASCII/Latin-1 characters?  It sure would be nice to
assume that
source code was in Unicode and thus gain access to some more interesting
characters to use for language semantics.

P.P.S.  Yes, I know about APL.

Gary W.
This topic is locked and can not be replied to.