Methods and :parameters

P

Pedro Del Gallego

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
 
R

Raj Sahae

Pedro said:
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
 
H

Hidetoshi NAGAI

From: "Pedro Del Gallego" <[email protected]>
Subject: Methods and :parameters
Date: Mon, 26 Feb 2007 10:57:59 +0900
Message-ID: said:
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
 
P

Pedro Del Gallego

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

Hidetoshi NAGAI

From: "Pedro Del Gallego" <[email protected]>
Subject: Re: Methods and :parameters
Date: Mon, 26 Feb 2007 22:02:56 +0900
Message-ID: said:
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 said:
self[prop[0..-2]] = args[0]
args[0]
else
# Else it will be "self.property(val)".
# Then call "self[ said:
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.
Are those OK?
 
K

Ken Bloom

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top