Methods and :parameters

Discussion in 'Ruby' started by Pedro Del Gallego, Feb 26, 2007.

  1. Hi all,

    I've a question about the :parameter notation.
    I want to write a method that can hold several optional paramters

    add_book :title=>"El quijote", :author=> "Miguel de Cervantes"
    add_book :title=>"El quijote", :author=> "Miguel de Cervantes", :tag=>"novel"
    add_book :title=>"El quijote"

    and i had write the add_book mehod like this :

    class Book
    attr_writer :title, :author
    end

    def add_book (book )
    puts "title : #{book.title} -- Author : #{book.author}"
    end

    but the interpreter said : ./bibliom.rb:7:in `add_book': undefined
    method `title' for {:title=>"El quijote", :author=>"Miguel de
    Cervantes"}:Hash (NoMethodError)

    I also try to put a hash object in the incoming parameter, like that :

    def add_book (book=[]) .... end

    My question is how can i wirte a method with several optional
    parameter and then acces they inside of the mehotd ?

    Thanks


    --
    -------------------------------------
    Pedro Del Gallego

    Email :
     
    Pedro Del Gallego, Feb 26, 2007
    #1
    1. Advertising

  2. Pedro Del Gallego

    Raj Sahae Guest

    Pedro Del Gallego wrote:
    > I've a question about the :parameter notation.
    > I want to write a method that can hold several optional paramters
    >
    > add_book :title=>"El quijote", :author=> "Miguel de Cervantes"
    > add_book :title=>"El quijote", :author=> "Miguel de Cervantes",
    > :tag=>"novel"
    > add_book :title=>"El quijote"

    To have a method with optional variables, assign them to nil in the
    declaration. If they aren't included in the method call, they will be
    set to nil.

    def add_book(title, author = nil, tag = nil)
    > but the interpreter said : ./bibliom.rb:7:in `add_book': undefined
    > method `title' for {:title=>"El quijote", :author=>"Miguel de
    > Cervantes"}:Hash (NoMethodError)

    It gives you this error because you are using attr_writer, which is
    equivalent to a def attr= method. In order to simply return a value,
    you should use attr_reader, or in case you want both, attr_accessor.

    I think what you want is along the lines of:

    class Book
    attr_accessor :title, :author, :tag

    def initialize(title, author = nil, tag = nil)
    self.title = title
    self.author = author
    self.tag = tag
    end

    def add_book
    puts "title: #{self.title} -- Author: #{self.author}"
    end
    end
     
    Raj Sahae, Feb 26, 2007
    #2
    1. Advertising

  3. From: "Pedro Del Gallego" <>
    Subject: Methods and :parameters
    Date: Mon, 26 Feb 2007 10:57:59 +0900
    Message-ID: <>
    > My question is how can i wirte a method with several optional
    > parameter and then acces they inside of the mehotd ?


    For example,
    -------------------------------------------------------------------
    class Book
    def initialize(properties = {})
    @props = {
    'title' => '',
    'author' => '',
    'tag' => nil,
    'price' => nil,
    'ISBN' => nil,
    }

    properties.each{|k, v|
    k = k.to_s
    raise ArgumentError, "unknown property: #{k}" unless @props.key?(k)
    @props[k] = v
    }
    end

    def method_missing(id, *args)
    prop = id.id2name
    case args.length
    when 1
    if prop[-1] == ?=
    self[prop[0..-2]] = args[0]
    args[0]
    else
    self[prop] = args[0]
    self
    end
    when 0
    self[prop]
    else
    super(id, *args)
    end
    end

    def [](prop)
    prop = prop.to_s
    raise ArgumentError, "unknown property: #{prop}" unless @props.key?(prop)
    @props[prop]
    end

    def []=(prop, val)
    prop = prop.to_s
    raise ArgumentError, "unknown property: #{prop}" unless @props.key?(prop)
    @props[prop] = val
    end
    end

    def add_book(props)
    book = Book.new(props)
    puts "case1: title : #{book.title} -- Author : #{book.author}"
    puts "case2: title : #{book[:title]} -- Author : #{book[:author]}"
    puts "case3: title : #{book['title']} -- Author : #{book['author']}"
    book
    end

    add_book :title=>"El quijote", :author=> "Miguel de Cervantes"
    add_book :title=>"El quijote", :author=> "Miguel de Cervantes", :tag=>"novel"
    add_book :title=>"El quijote"

    add_book :title=>"hogehoge", :language=>"Japanese" # => raise ArgumentError
    -------------------------------------------------------------------
    --
    Hidetoshi NAGAI ()
     
    Hidetoshi NAGAI, Feb 26, 2007
    #3
  4. Wow ... thats exactly what i was looking for :). Can you explain me
    how this override of the method_missing works? im a little bit lost
    right after the when statament begin ...

    > def method_missing(id, *args)
    > prop = id.id2name
    > case args.length
    > when 1
    > if prop[-1] == ?=
    > self[prop[0..-2]] = args[0]
    > args[0]
    > else
    > self[prop] = args[0]
    > self
    > end
    > when 0
    > self[prop]
    > else
    > super(id, *args)
    > end
    > end
    >


    Thanks again.

    --
    -------------------------------------
    Pedro Del Gallego

    Email :
     
    Pedro Del Gallego, Feb 26, 2007
    #4
  5. From: "Pedro Del Gallego" <>
    Subject: Re: Methods and :parameters
    Date: Mon, 26 Feb 2007 22:02:56 +0900
    Message-ID: <>
    > Wow ... thats exactly what i was looking for :). Can you explain me
    > how this override of the method_missing works? im a little bit lost
    > right after the when statament begin ...
    >
    > > def method_missing(id, *args)

    # Expect the unknown method as accessing to a property.
    > > prop = id.id2name

    # Get the method name string.
    > > case args.length

    # Check the number of arguments.
    > > when 1

    # If one argument, it will be a setter method.
    > > if prop[-1] == ?=

    # Is it "<property>="? (e.g. "self.property = val")
    # If so, call "self[<property>] = val".
    > > self[prop[0..-2]] = args[0]
    > > args[0]
    > > else

    # Else it will be "self.property(val)".
    # Then call "self[<property>] = val".
    > > self[prop] = args[0]
    > > self
    > > end
    > > when 0

    # If no argument, it will be a getter method.
    > > self[prop]
    > > else

    # If more than one argument, it will not a setter or getter.
    # So use "method_missing" of the super class.
    > > super(id, *args)
    > > end
    > > end


    Are those OK?
    --
    Hidetoshi NAGAI ()
     
    Hidetoshi NAGAI, Feb 26, 2007
    #5
  6. Pedro Del Gallego

    Ken Bloom Guest

    On Mon, 26 Feb 2007 10:57:59 +0900, Pedro Del Gallego wrote:

    > Hi all,
    >
    > I've a question about the :parameter notation. I want to write a method
    > that can hold several optional paramters
    >
    > add_book :title=>"El quijote", :author=> "Miguel de Cervantes"
    > add_book :title=>"El quijote", :author=> "Miguel de Cervantes",
    > :tag=>"novel" add_book :title=>"El quijote"
    >
    > and i had write the add_book mehod like this :
    >
    > class Book
    > attr_writer :title, :author
    > end
    >
    > def add_book (book )
    > puts "title : #{book.title} -- Author : #{book.author}"
    > end
    >
    > but the interpreter said : ./bibliom.rb:7:in `add_book': undefined
    > method `title' for {:title=>"El quijote", :author=>"Miguel de
    > Cervantes"}:Hash (NoMethodError)
    >
    > I also try to put a hash object in the incoming parameter, like that :
    >
    > def add_book (book=[]) .... end
    >
    > My question is how can i wirte a method with several optional parameter
    > and then acces they inside of the mehotd ?



    def add_book (book )
    puts "title : #{book[:title]} -- Author : #{book[:author]}"
    end

    When using the named parameter idiom, all of the named parameters are
    lumped together into a single hash which is passed as the last parameter.
    There's no point in defining the Book class -- it won't be used by this
    idiom.

    If you want to access the parameters as members, then you can construct
    an OpenStruct inside the method, like so

    require 'ostruct'

    def add_book book
    book=OpenStruct.new(book)
    puts "title : #{book.title} -- Author : #{book.author}"
    end

    but that's most likely overkill.

    --
    Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
    Department of Computer Science. Illinois Institute of Technology.
    http://www.iit.edu/~kbloom1/
     
    Ken Bloom, Feb 26, 2007
    #6
  7. > Are those OK?

    Perfect :). Thanks a lot.


    --
    -------------------------------------
    Pedro Del Gallego

    Email :
     
    Pedro Del Gallego, Feb 26, 2007
    #7
    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. Buster Copley
    Replies:
    5
    Views:
    568
    Gianni Mariani
    Jul 7, 2003
  2. Robert Brewer
    Replies:
    0
    Views:
    246
    Robert Brewer
    Oct 6, 2004
  3. Jason
    Replies:
    2
    Views:
    525
    Jonathan Mcdougall
    May 13, 2006
  4. Kees de Winter

    Attribute for Methods and Parameters

    Kees de Winter, Sep 21, 2007, in forum: ASP .Net
    Replies:
    4
    Views:
    324
    Kees de Winter
    Sep 21, 2007
  5. Kenneth McDonald
    Replies:
    5
    Views:
    342
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page