glejeune / Ruby-Graphviz

[MIRROR] Ruby interface to the GraphViz graphing tool
https://gitlab.com/glejeune/ruby-graphviz
Other
608 stars 116 forks source link

Unexplicable label duplication #116

Open stefankroes opened 8 years ago

stefankroes commented 8 years ago

Please consider the following code and output. Note that nodes A and B both have the same label (A). This is obviously unexpected behavior.

g = GraphViz.new :G, type: 'digraph'
options = { fontsize: 10 }
g.add_node 'A', options
g.add_node 'B', options
puts g.output canon: String
digraph G {
    node [label="\N"];
    A    [fontsize=10,
        label=A];
    B    [fontsize=10,
        label=A];
}

The following code does lead to the correct results:

require 'graphviz'
g = GraphViz.new :G, type: 'digraph'
g.add_node 'A', { fontsize: 10 }
g.add_node 'B', { fontsize: 10 }
puts g.output canon: String

However, the following variations do not:

require 'graphviz'
g = GraphViz.new :G, type: 'digraph'
options = { fontsize: 10 }
g.add_node 'A', options
g.add_node 'B', options.dup
puts g.output canon: String
require 'graphviz'
g = GraphViz.new :G, type: 'digraph'
options = { fontsize: 10 }
g.add_node 'A', options
g.add_node 'B', options.merge(fontsize: 11)
puts g.output canon: String

To me, this is totally amazing but I'm sure there is some explanation.

Tried on multiple Ruby versions from 1.9.3 to 2.3.0.

stefankroes commented 8 years ago

Update: In my more complex real-life scenario, the .dup does seem to solve the problems

stefankroes commented 8 years ago

In my more complex scenario, I'm calling dup every time, which also fixes the bug.

require 'graph'
g = GraphViz.new :G, type: 'digraph'
options = { fontsize: 10 }
g.add_node 'A', options.dup
g.add_node 'B', options.dup
puts g.output canon: String

The problem must be that the label is added to the options hash, in-place, but only if there is no label key in the options hash yet.