Help needed with this code please

Hi. I have a number of classes that use a module as a mixin. Not sure if
I have my terms correct there. Anyway here is one of the classes......
require 'predicate'
class Song
include Pred
@@songs = [ ]
attr_accessor :name, :album, :artist, :time, :year, :id, :in_libs
def initialize(name, album, artist, time, id, in_libs)
@name = name
@album = album
@time = time
@artist = artist
@id = id
@in_libs = in_libs
end

def to_s
puts "<< #{@name} >> by #{@artist} in their album #{@album}.\n"
end

def self.list
@@songs
end

def self.list_add=(val)
@@songs << val
end

end

.....................................

Here is the module....

module Pred
def isa?(target_class)
  instance_of?(target_class)
end
end

........................................
Here is another module that I use to fetch data form classes such as
Song........

module Tuneuts
def self.fetch(item, out = [])
all = Song.list + Actor.list + Album.list + Library.list
case
when item.instance_of?(String)
all.each do |obj|

if obj.name.downcase == item.downcase
then out << obj end end
if (out.length > 1)
  then MyErr.new("multiple_answer_error", item, "fetch").do_it end
when item.isa?
  all.each {|obj|
if obj.eql?(item) then out << obj end}
else MyErr.new("weird_item", item, "fetch").do_it
end
out.first
end
end
............................

The problem is Song.list (in the module Tuneuts) is returning nothing.
Am I missing something here?

I've attached the whole program as a zip file FYI.

Thanks for taking a look

Attachments:
http://www.ruby-forum.com/attachment/5233/problem.zip

···

--
Posted via http://www.ruby-forum.com/.

class Song

[snip]

  @@songs =

[snip]

  def self.list
    @@songs
  end

  def self.list_add=(val)
    @@songs << val
  end

end

[snip]

module Tuneuts
  def self.fetch(item, out = )
    all = Song.list + Actor.list + Album.list + Library.list

[snip]

  end
end

The problem is Song.list (in the module Tuneuts) is returning nothing.
Am I missing something here?

Maybe I'm missing something obvious, but I think the parts I didn't snip
out are the relevant bits:

Are you, at any point before calling Song.list, assigning anything to the
@@songs variable? From what I've seen, your @@songs variable is just an
empty list at the point you call Song.list in the Tuneuts module. As
such, it should be returning "nothing", in that it returns nothing but an
empty list.

Note that in my irb examples, I've saved all the code that was included
inline in your email in a single file called song.rb, and commented out
the `require "predicate"` part -- and moved the Pred module definition
above the Song class definition so the class could actually take
advantage of the module.

    ~> irb
    irb(main):001:0> load 'song.rb'
    => true
    irb(main):002:0> Song.list
    =>
    irb(main):003:0> puts Song.list
    => nil

If you assign something to it using your list_ad= method, however, you'll
then get something out of it:

    irb(main):004:0> Song.list_add = 'foo'
    => "foo"
    irb(main):005:0> Song.list
    => ["foo"]
    irb(main):006:0> puts Song.list
    foo
    => nil

Is that perhaps where you're having a problem?

···

On Fri, Oct 22, 2010 at 07:03:04AM +0900, Paul Roche wrote:

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Thanks for the reply. I think the problem lies in the library class. In
the def self.build_all method to be specific. Here I need to invoke
self.list_add=(val). I've managed it in the other classes but I am stuck
at Library class

···

--
Posted via http://www.ruby-forum.com/.

Hi. I'm bumping this question again with a simpler twist........

I have these methods......

def self.list
@@songs
end

def self.list_add=(val)
@@songs << val
end

in song.rb

···

-----------------------

I can successfully fetch in the 'songs'through a CSV file.

I am able to populate an array like this.....

songx = ObjectSpace.each_object(Song).to_a

I want to do the same thing using Song.list_add

---------------------

Any ideas?

--
Posted via http://www.ruby-forum.com/.

Understood. Thanks again

···

--
Posted via http://www.ruby-forum.com/.

Hi Jeremy. I'm back with a simplified version of the above problem. Here
is the code.....

Basically I now want to create a function that takes in data that has
been taken in from a csv file.

So I have this on my main file.......

songs = reader.read_in_songs(song_csv_file_name)

puts "\nBuilding Libraries..."
libs = Song.build_all(songs)

···

----------------------------------------------

here is the song class.........

class Song
attr_accessor :name, :owner
def initialize(name, owner)
@name = name
@owner = owner
end

def to_s
puts " #{@name} #{@owner}"
end

def self.build_all(songs)

## I want to be able to 'create song objects'(?) from the data taken in
from the csv file here

end

end

-------------------------------------------

Here is a rough idea I have so far, but it's returning nothing

songs = []

songs.each {|song| songs << Song.new(song.name, song.owner)}
-------------------------------

Do I have the right idea?

--
Posted via http://www.ruby-forum.com/.

Your current list_add implementation is designed to allow you to add one
Song instance at a time to the list. It's not clear what you really
want to do here. Maybe what you want to do instead is remove your
list_add method entirely and then have your list method simply return
the list generated from ObjectSpace:

def self.list
  ObjectSpace.each_object(Song).to_a
end

With that in place, you wouldn't need to have the list_add method
anymore. Of course a much better solution is to have whatever you're
using to load your CSV information call list_add for each Sing instance
it creates.

BTW, I downloaded your code earlier and tried to take a look at it.
Aside from the fact that you really need to pick an indenting convention
and stick to it (it will make your code *much* easier for others to
read), I'm struck my your use of class variables all over the place.
Why are you doing that, or more generally, what are you trying to
accomplish overall?

-Jeremy

···

On 10/22/2010 03:10 PM, Paul Roche wrote:

Hi. I'm bumping this question again with a simpler twist........

I have these methods......

def self.list
@@songs
end

def self.list_add=(val)
@@songs << val
end

in song.rb

-----------------------

I can successfully fetch in the 'songs'through a CSV file.

I am able to populate an array like this.....

songx = ObjectSpace.each_object(Song).to_a

I want to do the same thing using Song.list_add

Hi Jeremy. I'm back with a simplified version of the above problem. Here
is the code.....

Basically I now want to create a function that takes in data that has
been taken in from a csv file.

So I have this on my main file.......

songs = reader.read_in_songs(song_csv_file_name)

puts "\nBuilding Libraries..."
libs = Song.build_all(songs)

----------------------------------------------

here is the song class.........

class Song
attr_accessor :name, :owner
def initialize(name, owner)
@name = name
@owner = owner
end

def to_s
puts " #{@name} #{@owner}"
end

def self.build_all(songs)

## I want to be able to 'create song objects'(?) from the data taken in
from the csv file here

end

end

-------------------------------------------

Here is a rough idea I have so far, but it's returning nothing

songs =

your problem is that you create an empty array above, then below you
iterate same empty array and push nothing into it!

songs.each {|song| songs << Song.new(song.name, song.owner)}

this should get you going in the right direction, assuming your cvs
list is comma separated

# create a test cvs list

···

On Sat, Oct 23, 2010 at 8:41 PM, Paul Roche <prpaulroche@gmail.com> wrote:
#
cvslist =
cvslist << "song1,owner1" << "song2,owner2" << "song3,owner3"

# get song and owner strings
#
cvslist.each do |item|
song,owner = item.split /\s*,\s*/
  puts song
  puts owner
end

-------------------------------

Do I have the right idea?

--
Kind Regards,
Rajinder Yadav | DevMentor.org | Do Good! ~ Share Freely

GNU/Linux: 2.6.35-22-generic
Kubuntu x86_64 10.10 | KDE 4.5.1
Ruby 1.9.2p0 | Rails 3.0.1

Jeremy Bopp wrote in post #956417:

end

I want to do the same thing using Song.list_add

Your current list_add implementation is designed to allow you to add one
Song instance at a time to the list. It's not clear what you really
want to do here. Maybe what you want to do instead is remove your
list_add method entirely and then have your list method simply return
the list generated from ObjectSpace:

def self.list
  ObjectSpace.each_object(Song).to_a
end

With that in place, you wouldn't need to have the list_add method
anymore. Of course a much better solution is to have whatever you're
using to load your CSV information call list_add for each Sing instance
it creates.

BTW, I downloaded your code earlier and tried to take a look at it.
Aside from the fact that you really need to pick an indenting convention
and stick to it (it will make your code *much* easier for others to
read), I'm struck my your use of class variables all over the place.
Why are you doing that, or more generally, what are you trying to
accomplish overall?

-Jeremy

Thanks for taking a look.

I acknowledge your points, particularly about indentation.
To be honest, this is school work, not an assigment, more take home work
to experiment with, so the class variables are probably there for me to
improve on it. Could you recommend how I change tese to local variables
and make use of them? I'd like to stick with the list_add method.
Overall I am implementing this to learn differnt aspects such as CSV
files and mixin modules. So this could be considered the goal of the
program. I'd like to keep away from objectspace. This is where I'm stuck
at. I'm currently trying to utilize the list add method and .list. Again
thanks for taking a look. I hope this has mad eit a bit clearere. Any
advice would be welcomed

···

On 10/22/2010 03:10 PM, Paul Roche wrote:

--
Posted via http://www.ruby-forum.com/\.

Thanks for taking a look.

No problem. :wink:

I acknowledge your points, particularly about indentation.
To be honest, this is school work, not an assigment, more take home work
to experiment with, so the class variables are probably there for me to
improve on it. Could you recommend how I change tese to local variables
and make use of them? I'd like to stick with the list_add method.
Overall I am implementing this to learn differnt aspects such as CSV
files and mixin modules. So this could be considered the goal of the
program. I'd like to keep away from objectspace. This is where I'm stuck
at. I'm currently trying to utilize the list add method and .list. Again
thanks for taking a look. I hope this has mad eit a bit clearere. Any
advice would be welcomed

I suggest that you try breaking down your experiment into more atomic
parts to start. Then assemble them once you understand things better.
You don't want to muddle things by trying too many things all at once.
Build on a solid foundation.

First of all, mixins aren't the solution for everything. From what I've
seen in this project so far, there doesn't appear to be a need for
making your own unless you want to contrive a need. Of course,
contrivance can torture you later. Given that, I would start with
playing with CSV processing and see if you can figure out how to do your
work without mixins at all.

I noticed that Reader#read_in_songs returns an Array of Song instances.
Whatever code calls that method could store that value into whatever
kind of variable makes sense for future reference and processing. There
should be no need to use a class variable for that, really. Another
option might be to create a SongList class, instances of which are tied
to a particular file containing a list of songs. Then you pass around
instances of that class to methods that will process the songs in the list.

As far as mixins go, I wouldn't bother too much with trying to bake your
own at this point. Your Pred module looks like it should work, but all
it's really doing is providing an alias for the instance_of? method.
Unless you add something more meaningful to it, it's probably best to
just remove it from your code for now.

-Jeremy

···

On 10/22/2010 04:29 PM, Paul Roche wrote: