initialize instance variable problem

Discussion in 'Ruby' started by Cameron Vessey, Aug 28, 2010.

  1. Why does this return nil for @city?

    class Url
    def initialize(city,quary,catagory,minask,maxask)
    @city = city
    @quary = quary
    @cat = catagory
    @min = minask
    @max = maxask
    end

    puts @city

    end
    a = Url.new('spokane',"tires","pts","0","1000")
    a
    --
    Posted via http://www.ruby-forum.com/.
    Cameron Vessey, Aug 28, 2010
    #1
    1. Advertising

  2. 2010/8/28 Cameron Vessey <>:
    > Why does this return nil for @city?


    Because when you use @city outside a method definition, it is an
    instance variable of you *class* Url [1] and not of an instance of you
    class.

    add

    def city
    puts @city
    end

    and call a.city to get what you want.

    Cheers,

    JJ Fleck

    [1] I'm not 100% sure of the naming but what is sure is that the @city
    you use is *not* an instance method of your instance a.
    Jean-Julien Fleck, Aug 28, 2010
    #2
    1. Advertising

  3. I get what your saying,

    But the problem I'm having is I want to build a URL string from the
    intit parameters... I need to concantinate them and add some other
    stuff...

    So I guess I just pass them to the class and use them as parameters?..
    no need to init them as instance variables?.. alright...

    thanks for the reply I will mess with it.

    --
    Posted via http://www.ruby-forum.com/.
    Cameron Vessey, Aug 29, 2010
    #3
  4. Cameron Vessey

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Sat, Aug 28, 2010 at 11:17 AM, Cameron Vessey <>wrote:

    > Why does this return nil for @city?
    >
    > class Url
    > def initialize(city,quary,catagory,minask,maxask)
    > @city = city
    > @quary = quary
    > @cat = catagory
    > @min = minask
    > @max = maxask
    > end
    >
    > puts @city
    >
    > end
    > a = Url.new('spokane',"tires","pts","0","1000")
    > a
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >


    This is basically what Jean said, but I figured it might be easier to follow
    if you can actually see it.

    class Url
    # self is the class Url
    puts "outside initialize 1, self is #{self.inspect}"

    def initialize(city,quary,catagory,minask,maxask)
    @city = city
    @quary = quary
    @cat = catagory
    @min = minask
    @max = maxask
    # self is an instance of Url
    puts "Inside initialize 3, self is #{self.inspect}"
    end

    # self is the class Url
    puts "outside initialize 2, self is #{self.inspect}"

    def render
    # self is an instance of Url
    puts "Inside initialize 4, self is #{self.inspect}"
    @city + @quary + @cat + @min + @max
    end
    end


    a = Url.new('spokane',"tires","pts","0","1000")
    result = a.render
    puts "result is #{result.inspect}"
    Josh Cheek, Aug 29, 2010
    #4
  5. On 28.08.2010 18:17, Cameron Vessey wrote:
    > Why does this return nil for @city?
    >
    > class Url
    > def initialize(city,quary,catagory,minask,maxask)
    > @city = city
    > @quary = quary
    > @cat = catagory
    > @min = minask
    > @max = maxask
    > end
    >
    > puts @city
    >
    > end
    > a = Url.new('spokane',"tires","pts","0","1000")
    > a


    Others have identified the basic issue (your puts statement accesses a
    member of the class and not of the instance) but I'd like to add a few
    other remarks. First, the name Url might cause confusion because
    someone might think it is a generic URL handling class (like class URI
    for example).

    What you basically should do is add attribute accessors for your
    instance variables, e.g.

    class Url
    attr :city
    end

    Then you can do

    a = Url.new ...
    puts a.city

    But: you can make your life much simpler by resorting to Struct:

    CityUrl = Struct.new :city, :quary, :catagory, :minask, :maxask

    This gives you a proper initialize, attribute accessors and a few more
    things for free.

    irb(main):008:0> a = CityUrl.new('spokane',"tires","pts","0","1000")
    => #<struct CityUrl city="spokane", quary="tires", catagory="pts",
    minask="0", maxask="1000">
    irb(main):009:0> a.city
    => "spokane"

    Btw, from the naming and values of "minask" and "maxask" it seems these
    should be rather used with integer values. Even if you read them as
    strings from some sort of file your application logic will become much
    easier if you convert those strings on reading into ints and then go
    from there. Otherwise you will have to convert them all the time you
    want to use them which is inefficient, error prone (you might forget a
    location) and tedious to change if you need to at one point. Also, you
    depend on the format of the single source which might make it difficult
    to pull the data from other sources later. Basically it's best to
    always do something like

    external representation -> import (load) converts into internal
    representation -> work with that internal representation throughout the
    application -> export (store) converts to external representation

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Aug 29, 2010
    #5
    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. Tony Morris
    Replies:
    3
    Views:
    881
    Roedy Green
    Feb 4, 2006
  2. Gerry Sutton
    Replies:
    1
    Views:
    538
    Peter Otten
    Apr 16, 2005
  3. David Garamond
    Replies:
    5
    Views:
    238
    Ara.T.Howard
    Jun 8, 2004
  4. Martin Jansson
    Replies:
    11
    Views:
    231
  5. Leon Bogaert
    Replies:
    19
    Views:
    324
    Robert Klemme
    Mar 23, 2008
Loading...

Share This Page