define_method with super in the proc 
Author Message
 define_method with super in the proc

ran into a serious problemo! i'm trying to create a subclass with
Class.new and then override a method with define_method, using super (of
course) to call up to the superclass. ex-

  class A
    def doit

    end
  end

  def makeproc
    Proc.new {
      super

    }
  end

  B = ClassNew(A)
  B.class_eval { define_method(:doit, makeproc) }

the problem is that #makeproc is interpreting the super for itself and
thus reports an error of 'makeproc' super: no superclass method
'makeproc' (NameError). obviously that's not what i want. how strange.

around this?

~transami

  _(")_  dobee dobee do...
   \v/  
   ^ ^



Fri, 07 Jan 2005 18:22:26 GMT  
 define_method with super in the proc

Quote:

> the problem is that #makeproc is interpreting the super for itself and
> thus reports an error of 'makeproc' super: no superclass method
> 'makeproc' (NameError). obviously that's not what i want. how strange.



you're not getting tied to the makeproc's object, you're getting tied to
the class object B itself.

I expanded on your example:
  class A
    attr_reader :x, :y
    def doit

      puts "A.doit"
    end
  end

  def makeproc
    Proc.new {

      puts "B.doit " + self.inspect
    }
  end

  B = Class.new(A)
  B.class_eval {
    alias  doit_super_A doit
    define_method(:doit, makeproc )
  }
  b = B.new
  b.doit                   #=> B.doit B
  puts b.y                 #=> nil

By the output of "b.doit", you see that the proc is executed in the
context of the class object B, and not the instance.

Is this a bug? It violates my PoLS atleast. I'm running
ruby 1.6.6 (2001-12-26) [i586-linux-gnu] and
ruby 1.6.7 (2002-03-01) [i686-linux]

Quote:
> how do i work
> around this?

I was going to suggest passing :doit_super_A into the makeproc and using
self.send, but in light of the above that won't help much.

*back to scratching head*

--
(\[ Kent Dahl ]/)_    _~_    __[ http://www.stud.ntnu.no/~kentda/ ]___/~
 ))\_student_/((  \__d L b__/  NTNU - graduate engineering - 4. year  )
( \__\_?|?_/__/ ) _)Industrial economics and technological management(
 \____/_?_\____/ (____engineering.discipline_=_Computer::Technology___)



Sat, 08 Jan 2005 19:01:36 GMT  
 define_method with super in the proc

K> ruby 1.6.6 (2001-12-26) [i586-linux-gnu] and
K> ruby 1.6.7 (2002-03-01) [i686-linux]


        * eval.c (rb_call0): self in a block given to define_method now be
          switched to the receiver of the method.

Guy Decoux



Sat, 08 Jan 2005 19:16:24 GMT  
 define_method with super in the proc

Quote:

>    * eval.c (rb_call0): self in a block given to define_method now be
>      switched to the receiver of the method.

thank goodness. after reading kents post i was about to cry. guess its
time to upgrade.

--
~transami



Sat, 08 Jan 2005 19:37:42 GMT  
 define_method with super in the proc

Quote:


>         * eval.c (rb_call0): self in a block given to define_method now be
>           switched to the receiver of the method.

Thank you. Since this is on the main branch, I take it the best bet
would be to compile from CVS and stay on the 1.7.* branch, if we want to
use define_method.

However, after compiling it up (ruby 1.7.2 (2002-07-13) [i686-linux]),
I notice that this doesn't solve the super problem Tom had. (Which
probably means I probably was of on a big goose chase.)

Anyway, back to the original problem. Tom, you could alias the super
method and pass its aliased name into the makeproc and call it
explicitly:

  class A
    attr_reader :x, :y
    def doit

    end
  end

  def makeproc( supername )
    Proc.new {
      self.send(supername)

    }
  end

  B = Class.new(A)
  B.class_eval {
    alias  doit_super_A doit
    define_method(:doit, makeproc(:doit_super_A) )
  }
  b = B.new
  b.doit

HTH, and sorry for depressing you in my previous post :-)

--
(\[ Kent Dahl ]/)_    _~_    __[ http://www.stud.ntnu.no/~kentda/ ]___/~
 ))\_student_/((  \__d L b__/  NTNU - graduate engineering - 4. year  )
( \__\_?|?_/__/ ) _)Industrial economics and technological management(
 \____/_?_\____/ (____engineering.discipline_=_Computer::Technology___)



Sat, 08 Jan 2005 19:48:54 GMT  
 define_method with super in the proc
thanks kent,

well, i'm going to upgrade and try out this alias bit. i was surprised
to find my program working (under a simple test) even without the use of
#super, but it may because it was using the class and not the instance.
i'm a bit confused. so let me go into a little more detail and see what
pointers you(s) can give me.

basically, i have a class with an attribute like so:

  class A
    attr_accessor :a
  end

then i subclass it:

  B = Class.new(A)

i'm not sure if B should be capitalized, perhaps just b? anyway, then i
override #a= in B.

  B.class_eval { define_method(:a=, Proc.new { super; puts a })

so the idea for B is to have #a= still set a, but also to print a.

what's the best approach to solving this? it looks like i have to
upgrade for starters. then try aliasing. i'll try that. does anyone have
any other notions for accomplishing this? looks like building classes on
the fly ain't as smooth as the rest of ruby. but then again, at least
you can do it at all.

like i said, right now my program dosen't have the #super and yet it
seems to work. how does that make any sense?

~transami

Quote:



> >         * eval.c (rb_call0): self in a block given to define_method now be
> >           switched to the receiver of the method.

> Thank you. Since this is on the main branch, I take it the best bet
> would be to compile from CVS and stay on the 1.7.* branch, if we want to
> use define_method.

> However, after compiling it up (ruby 1.7.2 (2002-07-13) [i686-linux]),
> I notice that this doesn't solve the super problem Tom had. (Which
> probably means I probably was of on a big goose chase.)

> Anyway, back to the original problem. Tom, you could alias the super
> method and pass its aliased name into the makeproc and call it
> explicitly:

>   class A
>     attr_reader :x, :y
>     def doit

>     end
>   end

>   def makeproc( supername )
>     Proc.new {
>       self.send(supername)

>     }
>   end

>   B = Class.new(A)
>   B.class_eval {
>     alias  doit_super_A doit
>     define_method(:doit, makeproc(:doit_super_A) )
>   }
>   b = B.new
>   b.doit

> HTH, and sorry for depressing you in my previous post :-)

> --
> (\[ Kent Dahl ]/)_    _~_    __[ http://www.stud.ntnu.no/~kentda/ ]___/~
>  ))\_student_/((  \__d L b__/  NTNU - graduate engineering - 4. year  )
> ( \__\_?|?_/__/ ) _)Industrial economics and technological management(
>  \____/_?_\____/ (____engineering.discipline_=_Computer::Technology___)

--
~transami


Sat, 08 Jan 2005 21:01:14 GMT  
 define_method with super in the proc
Hi --

Quote:

> thanks kent,

> well, i'm going to upgrade and try out this alias bit. i was surprised
> to find my program working (under a simple test) even without the use of
> #super, but it may because it was using the class and not the instance.

One thing that may be involved is the fact that super is actually a
keyword, not a method.  That may have something to do with why it has
the effect it does (i.e., being triggered in relation to the method
where the proc is defined, instead of being called in the context of
the method that's being added).

Quote:
> i'm a bit confused. so let me go into a little more detail and see what
> pointers you(s) can give me.

> basically, i have a class with an attribute like so:

>   class A
>     attr_accessor :a
>   end

> then i subclass it:

>   B = Class.new(A)

> i'm not sure if B should be capitalized, perhaps just b? anyway, then i
> override #a= in B.

>   B.class_eval { define_method(:a=, Proc.new { super; puts a })

> so the idea for B is to have #a= still set a, but also to print a.

Why not the old-fashioned way?

  class A
    attr_accessor :a
  end

  class B < A
    def a=(x)
      super


    end
  end

[...]

Quote:
> like i said, right now my program dosen't have the #super and yet it
> seems to work. how does that make any sense?

Because you're using alias :-)  alias is a multi-purpose way of
creating a new name for an existing method.  super is a specialized
case which searches up the class hierarchy for a method of the same
name as the one it (super) is used in.

So you can, at least theoretically, use alias to mimic super.  But in
general, the two are quite different.  I've found it helpful to think
of them as operating along perpendicular axes.  alias is horizontal:
it creates a new name at the same logical and procedural level as the
old name.  super is vertical and, as I mentioned, specialized: its job
is to bump control up the inheritance chain, based on method name
similarity.

There have been discussions of this here, which you can track down if
interested, some in the context of the question of combining alias and
super (which I've never thought was practicable, since they address
different needs), and/or in the context of general concern about the
safety and cleanness of alias (which I think I do understand, though I
really like alias :-)

David

--
David Alan Black


Web:  http://pirate.shu.edu/~blackdav



Sat, 08 Jan 2005 21:54:04 GMT  
 define_method with super in the proc

Quote:


>> * eval.c (rb_call0): self in a block given to define_method now be
>> switched to the receiver of the method.

> thank goodness. after reading kents post i was about to cry. guess its
> time to upgrade.

Is this feasible?

class A
  def doit

  end
end

def makeproc

  #^ args can go before here
end

B = Class.new(A)
B.class_eval "def doit #{makeproc}; end"

b = B.new
b.doit
p b

produces:




Sat, 08 Jan 2005 22:29:43 GMT  
 define_method with super in the proc
Mr. Ogata,

        very nice! very nice indeed.

thank you,
transami

Quote:



> >> * eval.c (rb_call0): self in a block given to define_method now be
> >> switched to the receiver of the method.

> > thank goodness. after reading kents post i was about to cry. guess its
> > time to upgrade.

> Is this feasible?

> class A
>   def doit

>   end
> end

> def makeproc

>   #^ args can go before here
> end

> B = Class.new(A)
> B.class_eval "def doit #{makeproc}; end"

> b = B.new
> b.doit
> p b

> produces:



--
~transami


Sat, 08 Jan 2005 23:22:04 GMT  
 define_method with super in the proc
Hi --

Quote:

> Mr. Ogata,

>    very nice! very nice indeed.

> thank you,
> transami


> > class A
> >   def doit

> >   end
> > end

> > def makeproc

> >   #^ args can go before here
> > end

> > B = Class.new(A)
> > B.class_eval "def doit #{makeproc}; end"

> > b = B.new
> > b.doit
> > p b

> > produces:



I'm losing sight of the goal here.  What's the advantage of this kind
of indirectness and extra work, when you can just write the code?

  class B < A
    def doit
      super

    end
  end

Normally I would assume that a small example is encapsulating
something that one would want to do one a larger scale, but I'm not
sure what that would be here.  (By "here" I mean the question raised
in the whole thread, not just this example.)

David

--
David Alan Black


Web:  http://pirate.shu.edu/~blackdav



Sat, 08 Jan 2005 23:36:01 GMT  
 define_method with super in the proc

Quote:

> I'm losing sight of the goal here.  What's the advantage of this kind
> of indirectness and extra work, when you can just write the code?

>   class B < A
>     def doit
>       super

>     end
>   end

> Normally I would assume that a small example is encapsulating
> something that one would want to do one a larger scale, but I'm not
> sure what that would be here.  (By "here" I mean the question raised
> in the whole thread, not just this example.)

well here's my code (slight out of date now). you'll notice i have super
remarked out, and i'm just redefining the the method. but like i said i
don't know how this works exactly in some cases, i.e. when the method is
an assignment (#x=). (i didn't include any of the widget classes this
draws upon, but you can imagine)

    # Widget Factory
    #   Returns a new widget object of specialized widget class
    def WidgetFactory.new(widget, bindings={}, attributes={})

      # a string name will work too
      widget = widget.intern if widget.is_a?(String)

      # makes an anoynomous class as subclass of desired widget
      widgetClass = Class.new(WidgetFactory.const_get(widget))

      # specialize class via bindings
      bindings.each do |k, v|
        widgetClass.class_eval {
          define_method(k) { |*args|
            #super
            v[0].send(v[1], *args)
          }
        }
      end

      return widgetClass.new(attributes)

    end

so you see i'm sort of dynamically creating classes. does that help?

--
~transami



Sat, 08 Jan 2005 23:53:06 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Super Tagging and Super Invoice

2. super super ?

3. Segfault for define_method

4. define_method ()

5. TSR, proc near, proc far

6. PROC within a PROC DD override

7. i need my proc-1 to be the same as an existing proc-2

8. Ho do I invoke proc from within proc

9. proc without stack frame OR macro instead of proc

10. proc in proc

11. calling a proc from proc

12. Calling a proc within a proc in tcl/tk8.0

 

 
Powered by phpBB® Forum Software