Problem extending (adding methods) to class

I am trying to extend a class developed by someone else (its from the
ncurses-ruby lib). I need to add some fields and methods to it.

1. I tried directly extending it the usual way.
    class MyForm < FORM

  However, all attempts to access my methods would give a NoMethodError
on the base class Ncurses::FORM.

2. I then looked up the source and copied the following *on top* of my
class MyForm.

  module Form
    class FORM
      attr_reader :user_object

      def user_object=(obj)
        @user_object = obj
      end
    end
end

I changed user_object to "my_fields". This approach works, but means i
cannot actually extend the class. I need a heirarchy below this each
adding its methods and data.

Now I am wondering whether my approach is wrong. Is the class
locked/final in some way?

I am aware of an alternative appoach: create an instance of FORM in a
class (no more inheritance). Use method_missing to call methods of
original class. However, before i make changes, would like to understand
if I am doing something wrong here.

Thanks.

···

--
Posted via http://www.ruby-forum.com/.

Nit Khair wrote:

I am trying to extend a class developed by someone else (its from the
ncurses-ruby lib). I need to add some fields and methods to it.

On further thought I am wondering if being inside a module makes that
class different. Like some sort of static or factory class. Nothing
coming up on google on "module classes" or classes within modules.

Could someone explain this or point me to a link. I read that modules
cannot be instantiated or subclasses - fine. What of classes declared in
them ?

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

I am trying to extend a class developed by someone else (its from the
ncurses-ruby lib). I need to add some fields and methods to it.

1. I tried directly extending it the usual way.
   class MyForm < FORM

However, all attempts to access my methods would give a NoMethodError
on the base class Ncurses::FORM.

Methods you add to a subclass are not visible to instances of the
original class.

2. I then looked up the source and copied the following *on top* of my
class MyForm.

module Form
   class FORM
     attr_reader :user_object

     def user_object=(obj)
       @user_object = obj
     end
   end
end

I changed user_object to "my_fields". This approach works, but means i
cannot actually extend the class. I need a heirarchy below this each
adding its methods and data.

Now I am wondering whether my approach is wrong. Is the class
locked/final in some way?

No. If you want to add methods to it, you can just open it up and add
them:

   require 'rubygems'
   require 'ncurses'

   class Ncurses::Form::FORM
     def my_method
       puts "Hello"
     end
   end

   n = Ncurses::Form::FORM.new
   n.my_method # Hello

David

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Nit Khair wrote:

Nit Khair wrote:

I am trying to extend a class developed by someone else (its from the
ncurses-ruby lib). I need to add some fields and methods to it.

On further thought I am wondering if being inside a module makes that
class different. Like some sort of static or factory class. Nothing
coming up on google on "module classes" or classes within modules.

Could someone explain this or point me to a link. I read that modules
cannot be instantiated or subclasses - fine. What of classes declared in
them ?

why don't you take advantage of open classes ?

you can write this :

class MyClass
  attr_accessor :myfield
end

and then you can access myfield using any instance of that class . The
same goes with methods .

If you write :

class MyClass
  def my_new_method
     #some logic here
  end
end

then , all your objects will have that method .

···

--
Posted via http://www.ruby-forum.com/\.

No. If you want to add methods to it, you can just open it up and add
them:

   require 'rubygems'
   require 'ncurses'

   class Ncurses::Form::FORM
     def my_method
       puts "Hello"
     end
   end

   n = Ncurses::Form::FORM.new
   n.my_method # Hello

David

That is precisely what i did. It worked. But I am unable to further
subclass it. Methods I am adding to the subclass are giving
NoMethodErrors.

···

--
Posted via http://www.ruby-forum.com/\.

Lex Williams wrote:

Nit Khair wrote:

Nit Khair wrote:

I am trying to extend a class developed by someone else (its from the
ncurses-ruby lib). I need to add some fields and methods to it.

On further thought I am wondering if being inside a module makes that
class different. Like some sort of static or factory class. Nothing
coming up on google on "module classes" or classes within modules.

Could someone explain this or point me to a link. I read that modules
cannot be instantiated or subclasses - fine. What of classes declared in
them ?

why don't you take advantage of open classes ?

you can write this :

class MyClass
  attr_accessor :myfield
end

and then you can access myfield using any instance of that class . The
same goes with methods .

If you write :

class MyClass
  def my_new_method
     #some logic here
  end
end

then , all your objects will have that method .

Are you by any chance saying the same thing i have done above, when i
copied the Module Class thing from the original source and added my
method and data to it ?

However, this much is working, but i need a heirarchy. I am unable to
extend this and add methods to it.

If the original class was declared as:

Module MyClass
class MYCLASS
  attr_accessor :myfield
end
end

I can copy this, and add:
   attr_accessor :newfield
This is okay.

But when i do:

class AnotherClass < MYCLASS
  attr_accessor :anotherfield
end

then i get a NoMethodError pointing to MyClass::MYCLASS. I get no error
when instantiating AnotherClass, only when i access the method added.

I need a heirarchy of classes under Ncurses::FORM.

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

No. If you want to add methods to it, you can just open it up and add
them:

   require 'rubygems'
   require 'ncurses'

   class Ncurses::Form::FORM
     def my_method
       puts "Hello"
     end
   end

   n = Ncurses::Form::FORM.new
   n.my_method # Hello

David

That is precisely what i did. It worked. But I am unable to further
subclass it. Methods I am adding to the subclass are giving
NoMethodErrors.

Can you try this and tell me what you get?

   class MyForm < Ncurses::Form::FORM
     def a_new_method
       puts "Hi"
     end
   end

   MyForm.new.a_new_method

David

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Class defined inside a module behaves exactly the same as if she was defined
'outside' - it isn't 'static' in any way.

(Following notes may either help you or not - I haven't understood
totally where exactly your problem is.)

If you want to extend class ClassC defined inside module ModuleM , you can
either write

module ModuleM
  class ClassC
    # add new methods here
  end
end

or

class ModuleM::ClassC
  # add new methods here
end

Similarly if you want to subclass ClassC, you can do it inside ModuleM

module ModuleM
  class ClassD < ClassC
    # blah blah
  end
end

or outside:

class ClassD < ModuleM::ClassC
  # blah blah
end

Sorry if I didn't understand you at all...

···

Lex Williams wrote:
> Nit Khair wrote:
>> Nit Khair wrote:
>>> I am trying to extend a class developed by someone else (its from the
>>> ncurses-ruby lib). I need to add some fields and methods to it.
>>>
>>
>> On further thought I am wondering if being inside a module makes that
>> class different. Like some sort of static or factory class. Nothing
>> coming up on google on "module classes" or classes within modules.
>>
>> Could someone explain this or point me to a link. I read that modules
>> cannot be instantiated or subclasses - fine. What of classes declared in
>> them ?
>
> why don't you take advantage of open classes ?
>
> you can write this :
>
> class MyClass
> attr_accessor :myfield
> end
>
> and then you can access myfield using any instance of that class . The
> same goes with methods .
>
> If you write :
>
> class MyClass
> def my_new_method
> #some logic here
> end
> end
>
> then , all your objects will have that method .

Are you by any chance saying the same thing i have done above, when i
copied the Module Class thing from the original source and added my
method and data to it ?

However, this much is working, but i need a heirarchy. I am unable to
extend this and add methods to it.

If the original class was declared as:

>Module MyClass
> class MYCLASS
> attr_accessor :myfield
> end
>end

I can copy this, and add:
   attr_accessor :newfield
This is okay.

But when i do:

class AnotherClass < MYCLASS
  attr_accessor :anotherfield
end

then i get a NoMethodError pointing to MyClass::MYCLASS. I get no error
when instantiating AnotherClass, only when i access the method added.

I need a heirarchy of classes under Ncurses::FORM.

--
Posted via http://www.ruby-forum.com/\.

--
Zatímco velbloud dvouhrbý má hrby dva, Dromedár má jen jeden.

Jakub Pavlík jn. wrote:

module ModuleM
  class ClassC
    # add new methods here
  end
end

Thanks, this worked fine.

Similarly if you want to subclass ClassC, you can do it inside ModuleM

module ModuleM
  class ClassD < ClassC
    # blah blah
  end
end

Not tried this.

or outside:

class ClassD < ModuleM::ClassC
  # blah blah
end

THIS did not work. I got NoMethodErrors trying this out. I spent many
hours checking and trying to see if some other error was happening.

I needed:
class AForm < Ncurses::FORM

class BForm < AForm
and so on.

So finally, i removed the < clause abd created an instance in the
initializer. And used "method_missing" to call methods of that instance.
This is working perfectly, i can keep subclassing ... However, i still
want to understand what i did wrong. or what i am not understanding
about classes within modules.

···

---
Why create classes within modules ? Is it only a namespace issue - to
avoid clashes with other classes. Is it like java's package?

Should we always create modules and packages inside them in a project
with many classes ? Currently I have only one module with common stuff
and a heriarchy of classes under no module.
--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Fri, 3 Oct 2008, Nit Khair wrote:

Jakub Pavlík jn. wrote:

module ModuleM
  class ClassC
    # add new methods here
  end
end

Thanks, this worked fine.

Similarly if you want to subclass ClassC, you can do it inside ModuleM

module ModuleM
  class ClassD < ClassC
    # blah blah
  end
end

Not tried this.

or outside:

class ClassD < ModuleM::ClassC
  # blah blah
end

THIS did not work. I got NoMethodErrors trying this out. I spent many
hours checking and trying to see if some other error was happening.

I needed:
class AForm < Ncurses::FORM

I don't think it was exactly this, because there is no Ncurses::FORM.
Try the code in my previous post and see if it works for you. If not,
please post some actual code that triggers the error you're talking
about. I can't duplicate it.

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

David A. Black wrote:

Hi --

Similarly if you want to subclass ClassC, you can do it inside ModuleM
or outside:

class AForm < Ncurses::FORM

I don't think it was exactly this, because there is no Ncurses::FORM.
Try the code in my previous post and see if it works for you. If not,
please post some actual code that triggers the error you're talking
about. I can't duplicate it.

David

Maybe we are onto something. Your code works fine. But doesn't FORM.new
require a fields object ? I tried many variations so i cant remember
what it was but here is the last one I have before i rewrote.

include Ncurses
include Ncurses::Form

class RBForm < FORM
  attr_accessor :ffields
  def initialize(fields)
    super(fields)
    @ffields = fields
  end
  def set_ffields(fields)
    @ffields = fields
  end
  def get_ffields
    @ffields
  end
end

get_ffields throws a NoMethodError.
If i access ffields, that too gives an error.

It is instantiated thus:
    f=RBQueryForm.new(fields);

RBQueryForm is subclassed from RBForm.

See if you can spot the error here itself. Otherwise I will try to cut
and make a tiny version that you can run and see.

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Posted via http://www.ruby-forum.com/\.

Hi --

David A. Black wrote:

Hi --

Similarly if you want to subclass ClassC, you can do it inside ModuleM
or outside:

class AForm < Ncurses::FORM

I don't think it was exactly this, because there is no Ncurses::FORM.
Try the code in my previous post and see if it works for you. If not,
please post some actual code that triggers the error you're talking
about. I can't duplicate it.

David

Maybe we are onto something. Your code works fine. But doesn't FORM.new
require a fields object ? I tried many variations so i cant remember
what it was but here is the last one I have before i rewrote.

include Ncurses
include Ncurses::Form

class RBForm < FORM
attr_accessor :ffields
def initialize(fields)
   super(fields)
   @ffields = fields
end
def set_ffields(fields)
   @ffields = fields
end
def get_ffields
   @ffields
end
end

get_ffields throws a NoMethodError.
If i access ffields, that too gives an error.

It is instantiated thus:
   f=RBQueryForm.new(fields);

RBQueryForm is subclassed from RBForm.

See if you can spot the error here itself. Otherwise I will try to cut
and make a tiny version that you can run and see.

*Please* post some real code that contains the error. Otherwise it
just goes back and forth.

This code runs. I've changed super(fields) to super() because with an
argument I got an error (it expected zero arguments). I don't know
exactly what the fields are supposed to consist of so I've used a
placeholder ("abc").

require 'rubygems'
require 'ncurses'
include Ncurses
include Ncurses::Form

class RBForm < FORM
   attr_accessor :ffields
   def initialize(fields)
     super()
     @ffields = fields
   end
   def set_ffields(fields)
     @ffields = fields
   end
   def get_ffields
     @ffields
   end
end

RBForm.new("abc").set_ffields("abc")

David

···

On Fri, 3 Oct 2008, Nit Khair wrote:

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

David A. Black wrote:

Hi --

please post some actual code that triggers the error you're talking

include Ncurses
end
   f=RBQueryForm.new(fields);

RBQueryForm is subclassed from RBForm.

See if you can spot the error here itself. Otherwise I will try to cut
and make a tiny version that you can run and see.

*Please* post some real code that contains the error. Otherwise it
just goes back and forth.

This code runs. I've changed super(fields) to super() because with an
argument I got an error (it expected zero arguments). I don't know
exactly what the fields are supposed to consist of so I've used a
placeholder ("abc").

RBForm.new("abc").set_ffields("abc")

David

Sorry about not posting reeal code. I tried the same thing -- to bring
it down to one file, but it won't let me pass a parameter. When i say
only super() the sample is working. The original program goes ahead with
the field array - no error at that point. There are too many modules and
classes involved for me to put it all here. Still trying to post some
real code.

I thought you may straight away spot the error considering that I am
passing a param, and you are not. wait ...

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Posted via http://www.ruby-forum.com/\.

Nit Khair wrote:

David A. Black wrote:

Hi --

please post some actual code that triggers the error you're talking

OK David, I will attach a file that comes with ncurses-ruby.
I have subclassed FORM with MyForm and tried to call a method.

(Once it works You can exit using C-c or alt-c.)

Strangely in the samples we made, FORM and FIELD take no params. This is
outside of the ncurses environment. In the sample i sent you earlier, i
tried to create a FIELD object, but it would take no params !!!
So i had no option but to take an independent fully working sample and
add a few lines.

Attachments:
http://www.ruby-forum.com/attachment/2759/f3.rb

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Fri, 3 Oct 2008, Nit Khair wrote:

Nit Khair wrote:

David A. Black wrote:

Hi --

On Fri, 3 Oct 2008, Nit Khair wrote:

please post some actual code that triggers the error you're talking

OK David, I will attach a file that comes with ncurses-ruby.
I have subclassed FORM with MyForm and tried to call a method.

(Once it works You can exit using C-c or alt-c.)

Strangely in the samples we made, FORM and FIELD take no params. This is
outside of the ncurses environment. In the sample i sent you earlier, i
tried to create a FIELD object, but it would take no params !!!
So i had no option but to take an independent fully working sample and
add a few lines.

OK, I think what's happening here is that the FORM class is overriding
new, in such a way that it does not call initialize. So overriding
initialize doesn't do anything.

I don't have a solution worked out but I believe that's the issue.

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

David A. Black wrote:

OK, I think what's happening here is that the FORM class is overriding
new, in such a way that it does not call initialize. So overriding
initialize doesn't do anything.

I don't have a solution worked out but I believe that's the issue.

Sorry if this sounds silly, i forgot to mention that i *had* attached
the source in my prev mail (f3.rb). Did you run it?

Thanks a lot for your time and thoughts.

···

--
Posted via http://www.ruby-forum.com/\.

David is right.

Before the line
  raise "NULL" if my_form.get_fields().nil?

insert
  raise Ncurses::Form::FORM.singleton_methods(false).join(" ") #=> new

You'll see that FORM class has a singleton "new" method which always
returns a FORM object. Class#new is shadowed so you'll never get a
descendant object

  raise MyForm.new.class.inspect #=> Ncurses::Form::FORM

DelegateClass is a possible solution unless you want to muck with the
C sources.

--Cheers
--Ragav

···

On Oct 2, 7:54 pm, Nit Khair <sentinel.2...@gmx.com> wrote:

David A. Black wrote:
> OK, I think what's happening here is that the FORM class is overriding
> new, in such a way that it does not call initialize. So overriding
> initialize doesn't do anything.

> I don't have a solution worked out but I believe that's the issue.

Sorry if this sounds silly, i forgot to mention that i *had* attached
the source in my prev mail (f3.rb). Did you run it?

Thanks a lot for your time and thoughts.
--
Posted viahttp://www.ruby-forum.com/.

Hi --

···

On Fri, 3 Oct 2008, Nit Khair wrote:

David A. Black wrote:

OK, I think what's happening here is that the FORM class is overriding
new, in such a way that it does not call initialize. So overriding
initialize doesn't do anything.

I don't have a solution worked out but I believe that's the issue.

Sorry if this sounds silly, i forgot to mention that i *had* attached
the source in my prev mail (f3.rb). Did you run it?

Yes; that's how I figured out that initialize wasn't being called.

David

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

ragav wrote:

You'll see that FORM class has a singleton "new" method which always
returns a FORM object. Class#new is shadowed so you'll never get a
descendant object

  raise MyForm.new.class.inspect #=> Ncurses::Form::FORM

DelegateClass is a possible solution unless you want to muck with the
C sources.

--Cheers
--Ragav

Ah, i get it. Thanks for the link to DelegateClass - just had a look at
it.

For the moment, (as mentioned earlier), i created an instance of FORM,
and used method_missing to "delegate" calls to it after checking
respond_to?, now i can subclass that class as required.

Changing the C source will mean others will not be able to use, unless
they move to my modified source - don't want that. Thanks for the info.

So my question again is: are classes declared within a module
typically/always factory classes like this -- i mean with singleton new
methods?

Perhaps I should look thru the source code of Facets or some other
project to jump-start my ruby. Any suggestions?

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

ragav wrote:

You'll see that FORM class has a singleton "new" method which always
returns a FORM object. Class#new is shadowed so you'll never get a
descendant object

  raise MyForm.new.class.inspect #=> Ncurses::Form::FORM

DelegateClass is a possible solution unless you want to muck with the
C sources.

--Cheers
--Ragav

Ah, i get it. Thanks for the link to DelegateClass - just had a look at
it.

For the moment, (as mentioned earlier), i created an instance of FORM,
and used method_missing to "delegate" calls to it after checking
respond_to?, now i can subclass that class as required.

Why not use a module?

module MyForm
   attr_accessor :myfields
   def get_fields
     @myfields
   end
end

class Ncurses::Form::FORM
   include MyForm
end

Changing the C source will mean others will not be able to use, unless
they move to my modified source - don't want that. Thanks for the info.

So my question again is: are classes declared within a module
typically/always factory classes like this -- i mean with singleton new
methods?

No; it's relatively unusual (though not unheard of) to override new.

David

···

On Fri, 3 Oct 2008, Nit Khair wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!