0

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
user229044
  • 232,980
  • 40
  • 330
  • 338
msc
  • 67
  • 8
  • 1
    simple fix would be to change `derivations.push(sentence)` to `derivations.push(sentence.dup)` - this will push a copy of `sentence` at its present state to your `derivations` collection. – dinjas Apr 12 '18 at 19:13
  • Remember `$` is a **global** variable in Ruby and should not be used casually like this. – tadman Apr 12 '18 at 19:58

2 Answers2

2

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.

user229044
  • 232,980
  • 40
  • 330
  • 338
0

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

tadman
  • 208,517
  • 23
  • 234
  • 262