James Gray
8/11/2006 1:48:00 PM
On Aug 11, 2006, at 7:47 AM, Dark Ambient wrote:
> I'm working from Ruby for Rails book but want to try and just
> replicate some of the examples in Ruby alone.
> One method in particular is called whole_name and would give the user
> the ability to search a list by first_name, middle_name, or last_name.
If you want to make a method to search the the individual composers,
you will need to get them into some data structure (like an Array)
where you can scan through them.
> class Composer
>
> def listcomp (first_name, middle_name, last_name)
> f = first_name
> m = middle_name
> l = last_name
> end
What are you intending this method to do? Currently, it doesn't do
anything meaningful:
1. first_name, middle_name, and last_name are accepted as arguments
2. Each of those is assigned to another local variable
3. All six local variables are discarded as the method exits
> def whole_name
> first_name + " " +
> (if middle_name then middle_name + " " else "" end) +
> last_name
> end
> end
This method doesn't work because it uses local variables that don't
exist in this method. I believe this is your hang-up.
Inside a class, you keep data around by putting it into instance
variables (those start with an @ symbol). All methods of the class
can access the instance variables for the current object.
See if this helps explain things:
>> class Name
>> def initialize(first, last, middle = nil)
>> # assign these local variables to instance variables...
?> @first = first
>> @last = last
>> @middle = middle
>> end
>>
?> # create methods to read those instance variables...
?> attr_reader :first, :last, :middle
>>
?> def full
>> [@first, @middle, @last].join(" ").squeeze(" ")
>> end
>> end
=> nil
>> james = Name.new("James", "Gray", "Edward")
=> #<Name:0x31a5e0 @last="Gray", @first="James", @middle="Edward">
>> james.last
=> "Gray"
>> james.full
=> "James Edward Gray"
>> dana = Name.new("Dana", "Gray")
=> #<Name:0x314c44 @last="Gray", @first="Dana", @middle=nil>
>> dana.middle
=> nil
>> dana.full
=> "Dana Gray"
> comp1 = Composer.new
> comp2 = Composer.new
> comp3 = Composer.new
> comp4 = Composer.new
> comp5 = Composer.new
>
> comp1.listcomp("ludwig","van","bethoven")
> comp2.listcomp("wolfgang","amadeus","mozart")
> comp3.listcomp("franz", "joseph", "hayden")
> comp4.listcomp("George", "frederic", "Handel")
> comp5.listcomp("Johann", "sebastian", "bach")
Here's another idea:
>> composers = [ %w[ludwig van beethoven],
?> %w[wolfgan amadeus mozart],
?> %w[franz joseph hayden],
?> %w[george frederic handel],
?> %w[johann sebastian bach] ].map do |f, m, l|
?> Name.new(f, m, l)
>> end
=> [#<Name:0x356040 @last="van", @first="ludwig",
@middle="beethoven">, #<Name:0x35602c @last="amadeus",
@first="wolfgan", @middle="mozart">, #<Name:0x356018 @last="joseph",
@first="franz", @middle="hayden">, #<Name:0x356004 @last="frederic",
@first="george", @middle="handel">, #<Name:0x355ff0
@last="sebastian", @first="johann", @middle="bach">]
> Question - I'm having a problem calling to the class method
> whole_name. The method is defined without any arguments so how could
> it be called ?
whole_name() is not a class method, it is an instance method. You
know this because it is called on instances of the class, not the
class itself (new() is a class method).
I hope my examples above cleared up calling the methods.
> Question - Did I set up the class correctly , defining the new object
> outside of the class definition ? And would it be better to create an
> array (multidimensional) for the composers instead of initializing
> each one seperately ? (If this question makes sense)
See above.
Hope that helps.
James Edward Gray II