Closure's self

Curious thought --- what if I'd like to know the arity of the proc being
executed?

  proc{|x| arity }.call(1)

I see no way to do this, not even with the extended Binding class. I begin to
wonder (for this and other reasons) if a closure's "self" is doable? (at
least I think _closure_ is the right "scope" for this)

  proc{|x| this.arity }.call(1)

T.

"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag
news:200410121125.26956.transami@runbox.com...

Curious thought --- what if I'd like to know the arity of the proc being
executed?

  proc{|x| arity }.call(1)

I see no way to do this, not even with the extended Binding class.

Why do you need that? You *know* the arity because you define the
argument list between ||.

I begin to
wonder (for this and other reasons) if a closure's "self" is doable? (at
least I think _closure_ is the right "scope" for this)

No, it's not since self binds to the environment:

class Foo
  def get() lambda { self } end
end

f = Foo.new
x = f.get.call
# x refers f

Cheers

    robert

"trans. (T. Onoma)" <transami@runbox.com> writes:

Curious thought --- what if I'd like to know the arity of the proc being
executed?

  proc{|x| arity }.call(1)

I see no way to do this, not even with the extended Binding class. I begin to
wonder (for this and other reasons) if a closure's "self" is doable? (at
least I think _closure_ is the right "scope" for this)

  proc{|x| this.arity }.call(1)

Closures per se don't have selfs -- they're not objects. Consider

def frob &closure
  [lambda &closure, lambda &closure]
end

It gives two Procs with the same closure, but different selves.

Here's an extremely ugly kludge:

class Proc
  alias :real_call :call
  
  def call *args
    old_proc = $current_proc
    $current_proc = self
    real_call *args
    $current_proc = old_proc
  end
end

(lambda do |x|
    puts $current_proc.arity
    (lambda do |x, y|
        puts $current_proc.arity
      end).call nil, nil
    puts $current_proc.arity
  end).call nil

(It prints 1, 2, 1.)

Curious thought --- what if I'd like to know the arity of the proc being
executed?

proc{|x| arity }.call(1)

like this?

   harp:~ > irb
   irb(main):001:0> cb = proc{|a,b,c| cb.arity}
   => #<Proc:0xb75a0ecc@(irb):1>

   irb(main):002:0> p cb.call(0,1,2)
   3
   => nil

I see no way to do this, not even with the extended Binding class. I begin to
wonder (for this and other reasons) if a closure's "self" is doable? (at
least I think _closure_ is the right "scope" for this)

proc{|x| this.arity }.call(1)

i don't quite understand this - but i think 'self' must be Object, although you
could probably subclass Proc in a way that it used the 'with' trick or
something, in any case it seems you don't really need 'self' if you can name it
some other way.

maybe you could make a subclass that regeistered itself as a class var when
being called?

something like

   harp:~ > cat b.rb
   class CallBack < Proc
     class << self
       attr :this, true
     end
     def call(*a, &b)
       begin
         self.class.this = self
         super
       ensure
         self.class.this = nil
       end
     end
   end

   CallBack::new{|a| p CallBack::this.arity }.call(42) #=> 1

if you get my meaning?

cheers.

-a

···

On Wed, 13 Oct 2004, trans. (T. Onoma) wrote:
--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
When you do something, you should burn yourself completely, like a good
bonfire, leaving no trace of yourself. --Shunryu Suzuki

===============================================================================

"trans. (T. Onoma)" <transami@runbox.com> writes:

> Curious thought --- what if I'd like to know the arity of the proc being
> executed?
>
> proc{|x| arity }.call(1)
>
> I see no way to do this, not even with the extended Binding class. I begin to
> wonder (for this and other reasons) if a closure's "self" is doable? (at
> least I think _closure_ is the right "scope" for this)
>
> proc{|x| this.arity }.call(1)

Closures per se don't have selfs -- they're not objects. Consider

     Ah, but they are Objects (as you make use of below). It's just
that the binding used when their body is called that of their creation,
not of themselves.

Here's an extremely ugly kludge:

> class Proc
> alias :real_call :call
>
> def call *args
> old_proc = $current_proc
> $current_proc = self
> real_call *args
> $current_proc = old_proc
> end
> end
>
> (lambda do |x|
> puts $current_proc.arity
> (lambda do |x, y|
> puts $current_proc.arity
> end).call nil, nil
> puts $current_proc.arity
> end).call nil

(It prints 1, 2, 1.)

    We could make id somewhat nicer if we use the "set_local" defined a
few weeks back back on the list:

WARNING: CODE TYPED DIRECTLY INTO EMAIL USING VAGUELY RECALLED
            EXPERIMENTAL FEATURE FROM ANOTHER E-MAIL THREAD

class Proc
    alias :real_call :call
    def call *args
         binding.set_local("this_proc",self)
         real_call *args
        end
    end

or even something like

class Self_aware_proc << Proc
    def initialize(&block)
         super
         binding.set_local("this_proc",self)
         self
        end
    end

or (IIRC):

class Self_aware_proc << Proc
    def initialize(&block)
         super
         self["this_proc"] = self
        end
    end

-- Markus

···

On Tue, 2004-10-12 at 09:00, Mikael Brockman wrote:

Why do you need that? You *know* the arity because you define the
argument list between ||.

and

like this?

harp:~ > irb
irb(main):001:0> cb = proc{|a,b,c| cb.arity}
=> #<Proc:0xb75a0ecc@(irb):1>

irb(main):002:0> p cb.call(0,1,2)
3
=> nil

Well, my example was maybe too simplistic. Procs can be passed around, so, no,
you don't always have a "handle" on them. Moreover, 'this' refers to the
block actually, not really the Proc.

It seems I got my scope wrong, though. But I'm not sure what this scope is
yet.

I should also point out that this idea further derives from speculation (over
on suby-ruby) about internalized counters for #each blocks (and maybe a last?
and first?) eg-

  ["a","b","c"].each { |x| p this.counter, x }
  => 0
     "a"
     1
     "b"
     2
     "c"

but I want to focus on the block initself first --hence it's arity.

T.

···

On Tuesday 12 October 2004 11:49 am, Robert Klemme wrote:
On Tuesday 12 October 2004 12:04 pm, Ara.T.Howard@noaa.gov wrote:

Markus <markus@reality.com> writes:

···

On Tue, 2004-10-12 at 09:00, Mikael Brockman wrote:
> "trans. (T. Onoma)" <transami@runbox.com> writes:
>
> > Curious thought --- what if I'd like to know the arity of the proc being
> > executed?
> >
> > proc{|x| arity }.call(1)
> >
> > I see no way to do this, not even with the extended Binding class. I begin to
> > wonder (for this and other reasons) if a closure's "self" is doable? (at
> > least I think _closure_ is the right "scope" for this)
> >
> > proc{|x| this.arity }.call(1)
>
>
> Closures per se don't have selfs -- they're not objects. Consider

     Ah, but they are Objects (as you make use of below). It's just
that the binding used when their body is called that of their creation,
not of themselves.

Proc objects contain closures, but they *are* not closures. :slight_smile:

Point taken. I'd like to respond but I don't think my knife is
sharp enough to split the hair any finer than that without cutting
myself. If I were socrates, I might be tempted to ask "BTW, what is
this "closure" that a Proc contains?" but I think I can see where that
leads.

    -- Markus

···

On Tue, 2004-10-12 at 10:14, Mikael Brockman wrote:

Markus <markus@reality.com> writes:

> On Tue, 2004-10-12 at 09:00, Mikael Brockman wrote:
> > "trans. (T. Onoma)" <transami@runbox.com> writes:
> >
> > > Curious thought --- what if I'd like to know the arity of the proc being
> > > executed?
> > >
> > > proc{|x| arity }.call(1)
> > >
> > > I see no way to do this, not even with the extended Binding class. I begin to
> > > wonder (for this and other reasons) if a closure's "self" is doable? (at
> > > least I think _closure_ is the right "scope" for this)
> > >
> > > proc{|x| this.arity }.call(1)
> >
> >
> > Closures per se don't have selfs -- they're not objects. Consider
>
> Ah, but they are Objects (as you make use of below). It's just
> that the binding used when their body is called that of their creation,
> not of themselves.

Proc objects contain closures, but they *are* not closures. :slight_smile: