This is an automated email from the ASF dual-hosted git repository.

Cole-Greer pushed a commit to branch GValueFollowupTP4
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 61407da00fde087ec41cc0bcb2805f8c265b517d
Author: Cole Greer <[email protected]>
AuthorDate: Wed Jun 10 16:26:24 2026 -0700

    Replace Go GValue constructor with an exported-field struct
    
    Drops NewGValue and the unexported fields/getters in favor of a plain 
struct with exported Name and Value fields (construct via GValue{Name: ..., 
Value: ...}), which is more idiomatic Go. The String() and IsNil() helpers are 
retained; the Name()/Value() getters are removed as they are redundant with the 
exported fields.
    
    This removes the client-side nested-GValue guard that lived in the 
constructor, so Go no longer fails fast on a nested GValue (it surfaces as a 
downstream serialization error instead). Updates GremlinLang, the cucumber 
step, the unit tests, and the Go GValue doc example accordingly.
    
    Assisted-by: Kiro:claude-opus-4.8
---
 docs/src/reference/gremlin-variants.asciidoc     |  2 +-
 gremlin-go/driver/cucumber/cucumberSteps_test.go |  2 +-
 gremlin-go/driver/gValue.go                      | 33 +++---------
 gremlin-go/driver/gValue_test.go                 | 65 +++++-------------------
 gremlin-go/driver/gremlinlang.go                 |  6 +--
 5 files changed, 27 insertions(+), 81 deletions(-)

diff --git a/docs/src/reference/gremlin-variants.asciidoc 
b/docs/src/reference/gremlin-variants.asciidoc
index 521a7017bf..21a833b04f 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -303,7 +303,7 @@ the traversal to utilize a parameter in place of a literal.
 
 [source,go]
 ----
-g.V().Has("name", gremlingo.NewGValue("name", "marko"))
+g.V().Has("name", gremlingo.GValue{Name: "name", Value: "marko"})
 ----
 
 [[gremlin-go-scripts]]
diff --git a/gremlin-go/driver/cucumber/cucumberSteps_test.go 
b/gremlin-go/driver/cucumber/cucumberSteps_test.go
index 41286b85a7..1b2f58a2d3 100644
--- a/gremlin-go/driver/cucumber/cucumberSteps_test.go
+++ b/gremlin-go/driver/cucumber/cucumberSteps_test.go
@@ -921,7 +921,7 @@ func (tg *tinkerPopGraph) usingTheParameterDefined(name 
string, params string) e
        }
        val := parseValue(strings.Replace(params, "\\\"", "\"", -1), 
tg.graphName)
        if parameterize {
-               tg.parameters[name] = gremlingo.NewGValue(name, val)
+               tg.parameters[name] = gremlingo.GValue{Name: name, Value: val}
        } else {
                tg.parameters[name] = val
        }
diff --git a/gremlin-go/driver/gValue.go b/gremlin-go/driver/gValue.go
index 90992cb780..3fece49b1f 100644
--- a/gremlin-go/driver/gValue.go
+++ b/gremlin-go/driver/gValue.go
@@ -23,38 +23,21 @@ import (
        "fmt"
 )
 
-// GValue is a variable or literal value that is used in a Traversal. It is 
composed of a key-value pair where the key
-// is the name given to the variable and the value is the object that the 
variable resolved to.
+// GValue is a variable or literal value that is used in a Traversal. It is 
composed of a key-value
+// pair where Name is the name given to the variable and Value is the object 
that the variable
+// resolves to. Construct one directly with a struct literal, e.g. 
GValue{Name: "x", Value: 1}.
+// A GValue's Value must not itself be a GValue (GValues cannot be nested).
 type GValue struct {
-       name  string
-       value interface{}
-}
-
-// NewGValue creates a new GValue to be used in traversals. GValues cannot be 
nested, which is
-// the only restriction imposed on the name.
-func NewGValue(name string, value interface{}) GValue {
-       if _, ok := value.(GValue); ok {
-               panic("GValues cannot be nested")
-       }
-       return GValue{name, value}
-}
-
-// Name returns the name of the GValue.
-func (gv GValue) Name() string {
-       return gv.name
+       Name  string
+       Value interface{}
 }
 
 // IsNil determines if the value held is of a nil value.
 func (gv GValue) IsNil() bool {
-       return gv.value == nil
-}
-
-// Value returns the value held by the GValue.
-func (gv GValue) Value() interface{} {
-       return gv.value
+       return gv.Value == nil
 }
 
 // String returns the string representation of the GValue in the format 
"name=value".
 func (gv GValue) String() string {
-       return fmt.Sprintf("%v=%v", gv.name, gv.value)
+       return fmt.Sprintf("%v=%v", gv.Name, gv.Value)
 }
diff --git a/gremlin-go/driver/gValue_test.go b/gremlin-go/driver/gValue_test.go
index 90c74d4497..ffd766e46f 100644
--- a/gremlin-go/driver/gValue_test.go
+++ b/gremlin-go/driver/gValue_test.go
@@ -27,16 +27,16 @@ import (
 func TestGValue(t *testing.T) {
 
        t.Run("test simple gValue", func(t *testing.T) {
-               gVal := NewGValue("intVal", 2)
-               assert.Equal(t, "intVal", gVal.Name())
-               assert.Equal(t, 2, gVal.Value())
+               gVal := GValue{Name: "intVal", Value: 2}
+               assert.Equal(t, "intVal", gVal.Name)
+               assert.Equal(t, 2, gVal.Value)
                assert.False(t, gVal.IsNil())
        })
 
        t.Run("test gValue allow parameter reuse with arrays", func(t 
*testing.T) {
                g := NewGraphTraversalSource(nil, nil)
                val := [3]int{1, 2, 3}
-               param := NewGValue("ids", val)
+               param := GValue{Name: "ids", Value: val}
                gl := g.Inject(param).V(param).GremlinLang
                assert.Equal(t, "g.inject(ids).V(ids)", gl.GetGremlin())
                assert.Equal(t, val, gl.parameters["ids"])
@@ -45,7 +45,7 @@ func TestGValue(t *testing.T) {
        t.Run("test gValue allow parameter reuse with slices", func(t 
*testing.T) {
                g := NewGraphTraversalSource(nil, nil)
                val := []int{1, 2, 3}
-               param := NewGValue("ids", val)
+               param := GValue{Name: "ids", Value: val}
                gl := g.Inject(param).V(param).GremlinLang
                assert.Equal(t, "g.inject(ids).V(ids)", gl.GetGremlin())
                assert.Equal(t, val, gl.parameters["ids"])
@@ -54,7 +54,7 @@ func TestGValue(t *testing.T) {
        t.Run("test gValue allow parameter reuse with maps", func(t *testing.T) 
{
                g := NewGraphTraversalSource(nil, nil)
                val := map[string]int{"foo": 1, "bar": 2}
-               param := NewGValue("ids", val)
+               param := GValue{Name: "ids", Value: val}
                gl := g.Inject(param).V(param).GremlinLang
                assert.Equal(t, "g.inject(ids).V(ids)", gl.GetGremlin())
                assert.Equal(t, val, gl.parameters["ids"])
@@ -62,75 +62,38 @@ func TestGValue(t *testing.T) {
 
        t.Run("test gValue name not duplicated", func(t *testing.T) {
                g := NewGraphTraversalSource(nil, nil)
-               param1 := NewGValue("ids", [2]int{1, 2})
-               param2 := NewGValue("ids", [2]int{2, 3})
+               param1 := GValue{Name: "ids", Value: [2]int{1, 2}}
+               param2 := GValue{Name: "ids", Value: [2]int{2, 3}}
                assert.Panics(t, func() { g.Inject(param1).V(param2) }, 
"parameter with name ids already exists.")
        })
 
-       t.Run("test name starting with _ accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("_ids", [2]int{1, 2}) })
-       })
-
-       t.Run("test name starting with digit accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("1a", [2]int{1, 2}) })
-       })
-
-       t.Run("test numeric name accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("1", [2]int{1, 2}) })
-       })
-
-       t.Run("test mid-string underscore name accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("a_b", 1) })
-       })
-
-       t.Run("test empty-string name accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("", 1) })
-       })
-
-       t.Run("test mid-string dollar sign accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("a$b", 1) })
-       })
-
-       t.Run("test unicode letter name accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("café", 1) })
-       })
-
        t.Run("test IsNil returns true for nil value", func(t *testing.T) {
-               gv := NewGValue("x", nil)
+               gv := GValue{Name: "x", Value: nil}
                assert.True(t, gv.IsNil())
        })
 
        t.Run("test String representation", func(t *testing.T) {
-               gv := NewGValue("x", 1)
+               gv := GValue{Name: "x", Value: 1}
                assert.Equal(t, "x=1", gv.String())
        })
 
-       t.Run("test Go keyword name accepted", func(t *testing.T) {
-               assert.NotPanics(t, func() { NewGValue("for", 1) })
-       })
-
-       t.Run("test nested GValue rejected", func(t *testing.T) {
-               assert.Panics(t, func() { NewGValue("x", NewGValue("y", 1)) },
-                       "GValues cannot be nested")
-       })
-
        t.Run("test distinct but equal slices allowed under same name", func(t 
*testing.T) {
                g := NewGraphTraversalSource(nil, nil)
-               param1 := NewGValue("ids", []int{1, 2, 3})
-               param2 := NewGValue("ids", []int{1, 2, 3})
+               param1 := GValue{Name: "ids", Value: []int{1, 2, 3}}
+               param2 := GValue{Name: "ids", Value: []int{1, 2, 3}}
                assert.NotPanics(t, func() { g.Inject(param1).V(param2) })
        })
 
        t.Run("test gValue nested in child traversal merges bindings", func(t 
*testing.T) {
                g := NewGraphTraversalSource(nil, nil)
-               gl := g.V().Where(T__.Is(NewGValue("xx1", 1))).GremlinLang
+               gl := g.V().Where(T__.Is(GValue{Name: "xx1", Value: 
1})).GremlinLang
                assert.Equal(t, "g.V().where(__.is(xx1))", gl.GetGremlin())
                assert.Equal(t, 1, gl.parameters["xx1"])
        })
 
        t.Run("test gValue nested across multiple child traversals merges 
bindings", func(t *testing.T) {
                g := NewGraphTraversalSource(nil, nil)
-               gl := g.V().Union(T__.V(NewGValue("vid1", 1)), 
T__.V(NewGValue("vid4", 4))).GremlinLang
+               gl := g.V().Union(T__.V(GValue{Name: "vid1", Value: 1}), 
T__.V(GValue{Name: "vid4", Value: 4})).GremlinLang
                assert.Equal(t, "g.V().union(__.V(vid1),__.V(vid4))", 
gl.GetGremlin())
                assert.Equal(t, 1, gl.parameters["vid1"])
                assert.Equal(t, 4, gl.parameters["vid4"])
diff --git a/gremlin-go/driver/gremlinlang.go b/gremlin-go/driver/gremlinlang.go
index 8eb46509ab..4dc88d987f 100644
--- a/gremlin-go/driver/gremlinlang.go
+++ b/gremlin-go/driver/gremlinlang.go
@@ -244,14 +244,14 @@ func (gl *GremlinLang) argAsString(arg interface{}) 
(string, error) {
                }
                return v.GetGremlin("__"), nil
        case GValue:
-               key := v.Name()
-               value := v.Value()
+               key := v.Name
+               value := v.Value
                if val, ok := gl.parameters[key]; ok {
                        if !reflect.DeepEqual(val, value) {
                                panic(fmt.Sprintf("parameter with name '%v' 
already exists.", key))
                        }
                } else {
-                       gl.parameters[key] = v.Value()
+                       gl.parameters[key] = v.Value
                }
                return key, nil
        case uuid.UUID:

Reply via email to