user4023763
user4023763

Reputation:

Why is my ruby class behaving unexpectedly?

I have the following ruby class:

class Scheme
  attr_reader :id, :uri, :labels, :in_schemes, :top_concepts

  def initialize(id, uri, labels, in_schemes)
    @id = id,
    @uri = uri,
    @labels = labels
    @in_schemes = in_schemes
    @top_concepts = Array.new
  end
end

And I have the following method that traverses the given directory looking for files (they have names like "01", "01.01.00", etc.) containing a series of language-specific category labels (Sample below):

def make_schemes(catdir)
  concept_schemes = Array.new
  Dir.foreach(catdir) do |file|
    unless file == "." || file == ".."
      id = file.gsub(/\./,"").to_s
      uri = "/unbist/scheme/#{id}"
      labels = Array.new
      in_schemes = Array.new
      File.read("#{catdir}/#{file}").split(/\n/).each do |line|
        label = JSON.parse(line)
        labels << label
      end
      if id.size > 2
        in_schemes = ["/unbist","/unbist/#{id[0..1]}"]
      else
        in_schemes = ["/unbist"]
      end
      p "Making new concept scheme with id: #{id}"
      concept_scheme = Scheme.new(id, uri, labels, in_schemes)
      p concept_scheme
      concept_schemes << concept_scheme
    end
  end
  return concept_schemes
end

Sample category file, named "#{dir}/01". Each line is proper JSON, but the whole file, for reasons beyond the scope of this question, is not.

{ "text": "ﻢﺳﺎﺌﻟ ﻕﺎﻧﻮﻨﻳﺓ ﻮﺴﻳﺎﺴﻳﺓ", "language": "ar" }
{ "text": "政治和法律问题", "language": "zh" }
{ "text": "political and legal questions", "language": "en" }
{ "text": "questions politiques et juridiques", "language": "fr" }
{ "text": "ПОЛИТИЧЕСКИЕ И ЮРИДИЧЕСКИЕ ВОПРОСЫ", "language": "ru" }
{ "text": "cuestiones politicas y juridicas", "language": "es" }

The output I am getting is strange. The id variable in the make_schemes method is set properly prior to constructing the new Scheme, but the Scheme initializer seems to be confused somewhere and is applying the entire set of variables to the object's id variable. Here is some output for the above sample (cleaned newlines added for readability:

"Making new concept scheme with id: 01"
#<Scheme:0xa00ffc8 
@uri="/scheme/01", 
@labels=[{"text"=>"مسائل قانونية وسياسية", "language"=>"ar"}, {"text"=>"政治和法律问题", "language"=>"zh"}, {"text"=>"political and legal questions", "language"=>"en"}, {"text"=>"questions politiques et juridiques", "language"=>"fr"}, {"text"=>"ПОЛИТИЧЕСКИЕ И ЮРИДИЧЕСКИЕ ВОПРОСЫ", "language"=>"ru"}, {"text"=>"cuestiones politicas y juridicas", "language"=>"es"}], 
@id=["01", "/scheme/01", [{"text"=>"مسائل قانونية وسياسية", "language"=>"ar"}, {"text"=>"政治和法律问题", "language"=>"zh"}, {"text"=>"political and legal questions", "language"=>"en"}, {"text"=>"questions politiques et juridiques", "language"=>"fr"}, {"text"=>"ПОЛИТИЧЕСКИЕ И ЮРИДИЧЕСКИЕ ВОПРОСЫ", "language"=>"ru"}, {"text"=>"cuestiones politicas y juridicas", "language"=>"es"}]], 
@in_schemes=["/"], 
@top_concepts=[]>

What am I missing here? What is causing this? I have a constructor for a different class that works fine with similar logic. I'm baffled. Maybe there's an approach that would work better?

Upvotes: 0

Views: 32

Answers (1)

the Tin Man
the Tin Man

Reputation: 160621

Try fixing:

@uri = uri,

to:

@uri = uri

As is, you're telling Ruby:

@uri = uri, @labels = labels    

Which, as I read it, means you're assigning labels to an array of uri, @labels, then assigning that array to @uri.

Upvotes: 3

Related Questions