Forum: Ruby modules and classes question

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.
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-03 18:11
(Received via mailing list)
Hi,

This is a serious noob question.

I am trying to write a small library and have the following situation:

class Main
  //initializes connection

  def request(blabla)
  end
end

class Resource < Main
 //different API calls
 def call
    //bla bla
    request(call)
 end
end

I would like to let the user do something like the AWS library:
Library::Main.initialize_connection(data) // initializes everything
and then just:
Library::Resource.method // and this should work

In Main I have the function that fills the data, I just don't know how
to implement the Resource class.
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-03 19:44
Marcelo Barbudas wrote:
> Hi,
>
> This is a serious noob question.
>
> I am trying to write a small library and have the following situation:
>
> class Main
>   //initializes connection
>
>   def request(blabla)
>   end
> end
>
> class Resource < Main
>  //different API calls
>  def call
>     //bla bla
>     request(call)
>  end
> end
>
> I would like to let the user do something like the AWS library:
> Library::Main.initialize_connection(data) // initializes everything
> and then just:
> Library::Resource.method // and this should work
>
> In Main I have the function that fills the data, I just don't know how
> to implement the Resource class.

I'm not sure what your issue is, so let's start with this:

module Library

  class Main
    def Main.initialize_stuff
      puts "initializing"
    end
  end

  class Resource
    def Resource.meth
      puts "executing meth"
    end
  end

end

Library::Main.initialize_stuff
Library::Resource.meth

--output:--
initializing
executing meth

Now what do you want to do?
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-03 20:21
(Received via mailing list)
Hi,
>   class Resource
>     def Resource.meth
>       puts "executing meth"
>     end
>   end
>
> end
>
>
Thanks for the answer.

Resource has to call a function from Main, or return an error if Main
isn't initialized.

I made Resource a subclass of Main because I wanted it to be the main
connection class.
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-03 20:56
Marcelo Barbudas wrote:
> Hi,
>>   class Resource
>>     def Resource.meth
>>       puts "executing meth"
>>     end
>>   end
>>
>> end
>>
>>
> Thanks for the answer.
>
> Resource has to call a function from Main, or return an error if Main
> isn't initialized.
>
> I made Resource a subclass of Main because I wanted it to be the main
> connection class.

The next iteration of the code:

module Library

  class Main
    @@ready_to_go = false

    def Main.initialize
      puts "initializing"
      @@ready_to_go = true
    end

    def Main.do_stuff
      if not @@ready_to_go
        raise "error"
      else
        puts "doing stuff"
      end
    end

  end

  class Resource
    def Resource.meth
      Main.do_stuff
    end
  end

end

Library::Main.initialize
Library::Resource.meth

--output:--
initializing
doing stuff
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-03 21:12
(Received via mailing list)
Hi.
> The next iteration of the code:
>
This looks like just what I want. I'll try it and re-open the thread if
I get stuck again.


Thanks!
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-05-03 21:25
7stud -- wrote:
>

Another iteration.  Try this:

module Library

  class BaseResource
    @@ready_to_go = false

    def BaseResource.initialize
      puts "initializing"
      @@ready_to_go = true
    end

    def do_stuff
      if not @@ready_to_go
        raise "error"
      else
        puts "doing stuff"
      end
    end

  end

  class SpecializedResource < BaseResource
    def SpecializedResource.meth
      do_stuff
    end
  end

end

Library::BaseResource.initialize
Library::SpecializedResource.meth


That doesn't work.  When you write a method call without an object in
front of it:

  class SpecializedResource < BaseResource
    def SpecializedResource.meth
      do_stuff    #<-------****
    end
  end

the implicit caller is self.   Inside meth, self is equal to the object
that called meth.  The object that called meth can be seen in this line:

Library::SpecializedResource.meth

It's the class Library::SpecializedResource.  So inside meth, self is
equal to the Library::SpecializedResource class.  And the
Library:SpecializedResource class does not have a method named
do_stuff--only instances of that class have a method named
do_stuff(which is inherited from BaseResource).  To call the instance
method, you need an instance.  So you can do something like this:

 class SpecializedResource < BaseResource
    def SpecializedResource.meth
      sr = SpecializedResource.new
      sr.do_stuff
    end
  end
Fbb4d027695dfdf76bf448b15d7e306a?d=identicon&s=25 matt neuburg (Guest)
on 2009-05-03 22:15
(Received via mailing list)
7stud -- <bbxx789_05ss@yahoo.com> wrote:

> that called meth.
Inside meth, self is equal to the object that meth is inside when it is
called. It has nothing whatever to do with who *calls* meth. m.
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-04 18:13
(Received via mailing list)
Hi,
>  class SpecializedResource < BaseResource
>     def SpecializedResource.meth
>       sr = SpecializedResource.new
>       sr.do_stuff
>     end
>   end

This seems a little complicated, not very DRY to write this code for
every method.

How does AWS do it?

AWS::S3::Base.establish_connection!()
and then just:
Bucket.create('jukebox')
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-05 09:58
(Received via mailing list)
2009/5/4 Marcelo Barbudas <nostef@gmail.com>:
> method.
>
> How does AWS do it?
>
> AWS::S3::Base.establish_connection!()
> and then just:
> Bucket.create('jukebox')

I do not have insights into AWS beyond what can be gatherere from
http://amazon.rubyforge.org/.  I don't find this pattern very
appealing.  For something like this to work you need to resort to some
form of global state (global variable, constant, class instance
variable, thread local variable) which means there is potential for
problems when working with multiple threads.  Another issue is that it
is not obvious, i.e. you do not see that there is something
transported behind the scenes.

I would at least refrain from placing this pattern in a library unless
it is thread safe and it is sure that there will and can never be the
need for more than a single connection which seems doubtful in case of
AWS.

My 0.02EUR.

Kind regards

robert
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-05 19:46
(Received via mailing list)
> it is thread safe and it is sure that there will and can never be the
> need for more than a single connection which seems doubtful in case of
> AWS.
>
I understand. How do you mimic an ActiveResource like structure then?

Something like:
conn = Main.new(user, pass)
conn.resources.method_from_resource_class_that_uses_main_for
the_actual_request_method
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-06 11:35
(Received via mailing list)
2009/5/5 Marcelo Barbudas <nostef@gmail.com>:
>> I would at least refrain from placing this pattern in a library unless
> the_actual_request_method
Yes, or even

Main.connect(user, pass) do |conn|
  conn.resources.method_from_resource_class_that_uses_main_for
the_actual_request_method
end

Cheers

robert
3518ff338e5eee9b32eb1815daabc602?d=identicon&s=25 Marcelo Barbudas (Guest)
on 2009-05-06 18:35
(Received via mailing list)
> the_actual_request_method
> end
>

Right. How do write these classes though?
How would some really really basic Main, Resource classes look like?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-05-07 14:41
(Received via mailing list)
2009/5/6 Marcelo Barbudas <nostef@gmail.com>:
>> the_actual_request_method
>> end
>
> Right. How do write these classes though?
> How would some really really basic Main, Resource classes look like?

I'm lacking the time to go into this with more detail but maybe this
blog posting helps you as a start.

http://blog.rubybestpractices.com/posts/rklemme/00...

Note especially the gist with the full code of the example mentioned
at the end of the article.

Kind regards

robert
This topic is locked and can not be replied to.