msc
msc

Reputation: 67

How to stop overwriting previous strings pushed into an array?

I'm trying to push all the derivation of the sentence.

For example: The < animal > in the < object >

I want derivations to hold the expansions, so derivation[0] would have "The cat in the < object >", while derivation[1] would have "The cat in the hat".

However, all the derivations before getting overwritten by the final derivation.

How do I prevent this from happening?

while is_non_terminal?(sentence)
 $key = sentence.match(/(\<[a-zA-Z0-9_\-*]+\>)/)
 sentence.sub!(/(\<[a-zA-Z0-9_\-*]+\>)/){grammar[$key.to_s].sample.join(' ')}
 derivations.push(sentence)
 puts derivations.to_s
 #puts sentence
end

Upvotes: 0

Views: 139

Answers (2)

tadman
tadman

Reputation: 211670

A more Ruby way of tackling this is:

def subst(template, vars)
  template = template.dup
  derivations = [ ]

  while (template.sub!(/\<([a-zA-Z0-9_\-*]+)\>/) { vars[$1].sample })
    derivations << template.dup
  end

  derivations
end

Where that can work when called like:

subst("The <animal> in the <object>", 'animal' => [ 'cat' ], 'object' => [ 'hat' ]);
# => ["The cat in the <object>", "The cat in the hat"]

Note that this can go into an infinite loop if one of your substitutions contains text like <animal> which contains text like <animal> which contains text like <animal>...

Upvotes: 0

user229044
user229044

Reputation: 239382

You only have one string in your code, and your continually modifying it and pushing new references to it into an array. Each entry in your array is simply a reference to the same string.

You should use sub instead of sub! to return a modified copy of your string that you can push into the array, so that each iteration of the loop produces a new string instead of modifying the same string.

Upvotes: 2

Related Questions