modules and classes question

Discussion in 'Ruby' started by Marcelo Barbudas, May 3, 2009.

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

    --
    M.
     
    Marcelo Barbudas, May 3, 2009
    #1
    1. Advertising

  2. Marcelo Barbudas

    7stud -- Guest

    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?

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, May 3, 2009
    #2
    1. Advertising

  3. Hi,
    > 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
    >
    >

    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.

    --
    M.
     
    Marcelo Barbudas, May 3, 2009
    #3
  4. Marcelo Barbudas

    7stud -- Guest

    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

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, May 3, 2009
    #4
  5. 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!

    --
    M.
     
    Marcelo Barbudas, May 3, 2009
    #5
  6. Marcelo Barbudas

    7stud -- Guest

    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



    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, May 3, 2009
    #6
  7. Marcelo Barbudas

    matt neuburg Guest

    7stud -- <> wrote:

    > When you write a method call without an object in
    > front of it:
    >
    > class SpecializedResource < BaseResource
    > def SpecializedResource.meth
    > do_stuff #<-------****
    > end
    > end
    >
    > Inside meth, self is equal to the object
    > 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.

    --
    matt neuburg, phd = , http://www.tidbits.com/matt/
    Leopard - http://www.takecontrolbooks.com/leopard-customizing.html
    AppleScript - http://www.amazon.com/gp/product/0596102119
    Read TidBITS! It's free and smart. http://www.tidbits.com
     
    matt neuburg, May 3, 2009
    #7
  8. 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')

    --
    M.
     
    Marcelo Barbudas, May 4, 2009
    #8
  9. 2009/5/4 Marcelo Barbudas <>:
    > Hi,
    >>
    >> =A0class SpecializedResource < BaseResource
    >> =A0 =A0def SpecializedResource.meth
    >> =A0 =A0 =A0sr =3D SpecializedResource.new
    >> =A0 =A0 =A0sr.do_stuff
    >> =A0 =A0end
    >> =A0end

    >
    > This seems a little complicated, not very DRY to write this code for ever=

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

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, May 5, 2009
    #9

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

    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

    --
    M.
     
    Marcelo Barbudas, May 5, 2009
    #10
  11. 2009/5/5 Marcelo Barbudas <>:
    >
    >> I do not have insights into AWS beyond what can be gatherere from
    >> http://amazon.rubyforge.org/. =A0I don't find this pattern very
    >> appealing. =A0For 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. =A0Another 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.
    >>

    >
    > I understand. How do you mimic an ActiveResource like structure then?
    >
    > Something like:
    > conn =3D Main.new(user, pass)
    > conn.resources.method_from_resource_class_that_uses_main_for
    > 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

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, May 6, 2009
    #11

  12. >> Something like:
    >> conn = Main.new(user, pass)
    >> conn.resources.method_from_resource_class_that_uses_main_for
    >> 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
    >


    Right. How do write these classes though?
    How would some really really basic Main, Resource classes look like?


    --
    M.
     
    Marcelo Barbudas, May 6, 2009
    #12
  13. 2009/5/6 Marcelo Barbudas <>:
    >
    >>> Something like:
    >>> conn =3D Main.new(user, pass)
    >>> conn.resources.method_from_resource_class_that_uses_main_for
    >>> the_actual_request_method

    >>
    >> Yes, or even
    >>
    >> Main.connect(user, pass) do |conn|
    >> =A0conn.resources.method_from_resource_class_that_uses_main_for
    >> 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/002_Writing_Block_Methods.h=
    tml

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

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, May 7, 2009
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Remy Cool
    Replies:
    1
    Views:
    437
    Remy Cool
    Aug 27, 2003
  2. ImpalerCore
    Replies:
    0
    Views:
    865
    ImpalerCore
    Mar 10, 2011
  3. August0866
    Replies:
    1
    Views:
    117
    Sebastian Hungerecker
    Mar 17, 2008
  4. Alpha Blue
    Replies:
    0
    Views:
    108
    Alpha Blue
    Jan 30, 2010
  5. Geometric Patterns
    Replies:
    2
    Views:
    102
    7stud --
    May 8, 2011
Loading...

Share This Page