included module and scope confusion

Discussion in 'Ruby' started by hmmm, Jan 10, 2006.

  1. hmmm

    hmmm Guest

    ------=_Part_6722_2615668.1136920311217
    Content-Type: text/plain; charset=ISO-8859-1
    Content-Transfer-Encoding: quoted-printable
    Content-Disposition: inline

    I am confused about modules and scope.

    Here is a module:

    module Crumbs
    MAX_CRUMBS =3D 10

    def self.included(mod)
    def cookies
    return @cookies =3D=3D nil ? Hash.new : @cookies
    end
    end

    def crumb_new( controller, action, params )
    cstr =3D controller + "^" + action
    if params !=3D nil && params.keys !=3D nil
    params.keys.each {|p|
    if params[p] !=3D nil
    cstr << "^" << p << "^" << params[p]
    end
    }
    end
    return cstr
    end

    def crumb_add( bite )
    cbs =3D @cookies
    puts cbs.class
    cbs =3D cbs[:rdf_crumbs]
    if cbs =3D=3D nil
    puts "crumb_add::cbs is nil!"
    cbs =3D[bite]
    else
    puts "crumb_add::cbs is OK!"
    cbs =3D cbs.split("|")
    #don't add a redundant
    if cbs.last =3D=3D bite
    return
    end
    # add to
    cbs << bite
    # cap the cookie queue at 5 using fifo
    if cbs.length > @@MAX_CRUMBS
    cbs.delete_at(0)
    end
    end
    crumbs_set( cbs )
    end

    def crumbs_set( mouthful )
    cr =3D ""
    mouthful.each { |m|
    if cr =3D=3D ""
    cr =3D m
    else
    cr << "|" << m
    end
    }
    puts cookies.class
    cookies[:rdf_crumbs] =3D cr
    end

    def get_crumbs()
    crs =3D @cookies["rdf_crumbs"]
    if crs =3D=3D nil
    return []
    else
    return crs.split("|")
    end
    end

    end
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D

    Here is a unit test:
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D
    class Bread
    include Crumbs
    def initialize
    @cookies =3D Hash.new
    end
    end

    class CrumbTest < Test::Unit::TestCase

    attr :bread

    def setup
    @bread =3D Bread.new
    end

    def test_crumbs_simple
    @params =3D Hash.new
    bite =3Dbread.crumb_new( "test1", "test_action", @params )
    bread.crumb_add(bite)
    puts bite
    bite =3Dbread.crumb_new( "test2", "test_action_2", @params )
    bread.crumb_add(bite)
    puts bite
    bite =3Dbread.crumb_new( "test3", "test_action_3", @params )
    bread.crumb_add(bite)
    puts bite
    assert bite =3D=3D "test3^test_action_3"
    bites =3Dbread.get_crumbs()
    puts bites.class
    assert_equal bites.length, 3
    end
    end

    Here is the output:
    ------------------------------------------
    test cookies! on Bread
    Hash
    crumb_add::cbs is nil!
    sets Hash with test1^test_action
    has 1
    test1^test_action
    Hash
    crumb_add::cbs is nil!
    sets Hash with test2^test_action_2
    has 1
    test2^test_action_2
    Hash
    crumb_add::cbs is nil!
    sets Hash with test3^test_action_3
    has 1
    test3^test_action_3
    ------------------------------------------

    And:
    ------------------------------------------
    Test::Unit::AssertionFailedError: <1> expected but was <3>.
    test/unit/crumbs_test.rb:62:in `test_crumbs_simple'
    ------------------------------------------

    I have tried different ways, but can't get the Correct Way to have a module
    insert a variable into the Class that includes it. In this case it should
    inject a @cookies hash, but in tests @cookies always gets reset to
    Hash.new...

    Excuse the inconsistencies in the code (towards @cookies) b/c I can't seem
    to figure out the proper way.

    So how do you add instance vars to a class from a module and how to
    reference that attribute? Or is this not the Right Ruby Way?

    I have a lot of confusion about modules... suppose its my java funk :/

    Please point me to any more docs on modules besides the ruby-lang snippet.

    -netcam

    ------=_Part_6722_2615668.1136920311217--
     
    hmmm, Jan 10, 2006
    #1
    1. Advertising

  2. hmmm

    hmmm Guest

    ------=_Part_6830_2952731.1136921080428
    Content-Type: text/plain; charset=ISO-8859-1
    Content-Transfer-Encoding: quoted-printable
    Content-Disposition: inline

    Before I was mixing (include) Crumbs on the unit test class and I think
    there was a name collision with the rails test_helper.rb file and @cookies
    hence it got me all confused.

    Ok here is what I did, and it seems simple. But a better way it seems woul=
    d
    to do it transparently to the subclass on the module, so if anyone knows
    how, divulge. I don't want to have to declare the attr_reader :cookies on
    the Class.

    class Bread
    include Crumbs

    attr_reader :cookies

    def initialize
    @cookies =3D Hash.new
    end
    end

    module Crumbs

    # def self.included(mod)
    # puts "test cookies! on #{mod}"
    # def mod.cookies
    # if @cookies =3D=3D nil
    # @cookies =3D Hash.new
    # end
    # return @cookies
    # end
    # end

    #----------------------------------------
    #--------------begin/ cookie crumbs mixin
    #----------------------------------------
    MAX_CRUMBS =3D 10

    def crumbs_clear
    if @cookies !=3D nil and @cookies["rdf_crumbs"] !=3D nil
    @cookies.delete "rdf_crumbs"
    end
    end

    def crumb_new( controller, action, params )
    cstr =3D controller + "^" + action
    if params !=3D nil && params.keys !=3D nil
    params.keys.each {|p|
    if params[p] !=3D nil
    cstr << "^" << p << "^" << params[p]
    end
    }
    end
    return cstr
    end

    def crumb_add( bite )
    cbs =3D @cookies
    puts cbs.class
    cbs =3D cbs["rdf_crumbs"]
    if cbs =3D=3D nil
    puts "crumb_add::cbs is nil!"
    cbs =3D[bite]
    else
    puts "crumb_add::cbs is OK!"
    cbs =3D cbs.split("|")
    #don't add a redundant
    if cbs.last =3D=3D bite
    return
    end
    # add to
    cbs << bite
    # cap the cookie queue at 5 using fifo
    if cbs.length > MAX_CRUMBS
    cbs.delete_at(0)
    end
    end

    crumbs_set( cbs )
    end

    def crumbs_set( mouthful )
    cr =3D ""
    mouthful.each { |m|
    if cr =3D=3D ""
    cr =3D m
    else
    cr << "|" << m
    end
    }
    puts "sets #{@cookies.class} with #{cr}"
    if @cookies =3D=3D nil
    @cookies =3D Hash.new
    end
    @cookies["rdf_crumbs"]=3Dcr
    puts "has #{@cookies.keys.length}"
    end

    def crumb_del( bite )
    crs =3D cookies[:rdf_crumbs]
    if crs !=3D nil
    crs =3D crumbs.split("|")
    c2 =3D""
    crs.each { |c|
    if crs[c] !=3D bite
    if c2 =3D=3D ""
    c2 =3D c
    else
    c2 << "|" << c
    end
    end
    }
    cookies[:rdf_crumbs] =3Dc2
    end
    end

    def get_crumbs()
    crs =3D @cookies["rdf_crumbs"]
    if crs =3D=3D nil
    return []
    else
    return crs.split("|")
    end
    end

    #----------------------------------------
    #--------------end/ cookie crumbs mixin
    #----------------------------------------
    end

    ------=_Part_6830_2952731.1136921080428--
     
    hmmm, Jan 10, 2006
    #2
    1. Advertising

  3. hmmm

    hmmm Guest

    ------=_Part_7686_11943162.1136929547534
    Content-Type: text/plain; charset=ISO-8859-1
    Content-Transfer-Encoding: quoted-printable
    Content-Disposition: inline

    Ok here is the final version...

    Unit Test:
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D
    class Bread
    include Crumbs
    def cookies
    @cookies ||=3D Hash.new
    end
    def initialize
    @cookies =3D Hash.new
    end
    end

    class CrumbTest < Test::Unit::TestCase

    attr :bread

    def setup
    @bread =3D Bread.new
    end

    # Simple add/delete/clear tests
    def test_crumbs_simples
    @params =3D Hash.new
    bite =3Dbread.crumb_new( "test1", "test_action", @params )
    bread.crumb_add(bite)
    bite =3Dbread.crumb_new( "test2", "test_action_2", @params )
    bread.crumb_add(bite)
    bite =3Dbread.crumb_new( "test3", "test_action_3", @params )
    bread.crumb_add(bite)
    assert bite =3D=3D "test3^test_action_3"
    bites =3Dbread.get_crumbs()
    assert_equal bites.length, 3
    bread.crumbs_clear()
    bites =3Dbread.get_crumbs()
    assert_equal bites.length, 0
    bite =3Dbread.crumb_new( "test1", "test_action", @params )
    bread.crumb_add(bite)
    bread.crumb_del(bite)
    bites =3Dbread.get_crumbs()
    assert_equal bites.length, 0
    end

    def test_crumbs_params
    bite =3Dbread.crumb_new( "test1", "test_action",
    {"filter"=3D>"s`divx:divx"})
    bread.crumb_add(bite)
    bites =3Dbread.get_crumbs()
    assert_equal bites[0], bite
    end
    end


    And the crumbs module:
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D

    module Crumbs
    #----------------------------------------
    #--------------begin/ cookie crumbs mixin
    #----------------------------------------
    MAX_CRUMBS =3D 10

    public
    def crumbs_clear
    if cookies !=3D nil and cookies[:rdf_crumbs] !=3D nil
    cookies.delete :rdf_crumbs
    end
    end

    def crumb_new( controller, action, params )
    cstr =3D controller + "^" + action
    if params !=3D nil && params.keys !=3D nil
    params.keys.each {|p|
    if params[p] !=3D nil
    cstr << "^" << p << "^" << params[p]
    end
    }
    end
    return cstr
    end

    def crumb_add( bite )
    cbs =3D cookies[:rdf_crumbs]
    if (cbs =3D=3D nil or cbs =3D=3D "") or (cbs.instance_of? Array and cbs=
    length=3D=3D0)
    cbs =3D[bite]
    else
    cbs =3D cbs.split("|")
    #don't add a redundant
    if cbs.last =3D=3D bite
    return
    end
    # add to
    cbs << bite
    # cap the cookie queue at 5 using fifo
    if cbs.length > MAX_CRUMBS
    cbs.delete_at(0)
    end
    end

    crumbs_set( cbs )
    end

    def crumbs_set( mouthful )
    cr =3D ""
    mouthful.each { |m|
    if cr =3D=3D ""
    cr =3D m
    else
    cr << "|" << m
    end
    }
    cookies[:rdf_crumbs]=3Dcr
    end

    def crumb_del( bite )
    crs =3D cookies[:rdf_crumbs]
    if crs !=3D nil
    crs =3D crs.split("|")
    c2 =3D""
    crs.each { |c|
    if c !=3D bite
    if c2 =3D=3D ""
    c2 =3D c
    else
    c2 << "|" << c
    end
    end
    }
    cookies[:rdf_crumbs] =3Dc2
    end
    end

    def get_crumbs()
    crs =3D cookies[:rdf_crumbs]
    if crs =3D=3D nil
    return []
    else
    return crs.split("|")
    end
    end

    #----------------------------------------
    #--------------end/ cookie crumbs mixin
    #----------------------------------------
    end

    ------=_Part_7686_11943162.1136929547534--
     
    hmmm, Jan 10, 2006
    #3
  4. hmmm wrote:

    </snip>

    > I have tried different ways, but can't get the Correct Way to have a
    > module insert a variable into the Class that includes it. In this
    > case it should inject a @cookies hash, but in tests @cookies always
    > gets reset to Hash.new...


    Of course because you assign it in initialize.

    Two options:

    1 Lazy init: You need to define cookies differently and access it always
    through the getter method (attachment ex1.rb)

    2 Init during constructor: you need to define #initialize in the module
    and either leave initialize out of Bread or use super (attachment ex2.rb)

    Module#included is completely wrong here as you do not want to do anything
    to the class that uses the mod.

    > Excuse the inconsistencies in the code (towards @cookies) b/c I can't
    > seem to figure out the proper way.
    >
    > So how do you add instance vars to a class from a module and how to
    > reference that attribute? Or is this not the Right Ruby Way?
    >
    > I have a lot of confusion about modules... suppose its my java funk :/


    Apparently. :)

    > Please point me to any more docs on modules besides the ruby-lang
    > snippet.




    HTH

    Kind regards

    robert
     
    Robert Klemme, Jan 11, 2006
    #4
    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. Steven T. Hatton
    Replies:
    9
    Views:
    488
  2. gyro
    Replies:
    1
    Views:
    249
    Diez B. Roggisch
    Feb 14, 2009
  3. Replies:
    2
    Views:
    105
  4. Prince Nez
    Replies:
    3
    Views:
    249
    Robert Klemme
    Aug 18, 2009
  5. Andrew Falanga
    Replies:
    2
    Views:
    202
    Andrew Falanga
    Nov 22, 2008
Loading...

Share This Page