From 83aa84f12df78a84df9ed50de152140e54d0be5f Mon Sep 17 00:00:00 2001 From: st0012 Date: Sun, 6 Oct 2019 14:48:07 +0800 Subject: [PATCH] Implement Object#tap --- vm/class.go | 12 ++++++++++++ vm/object_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/vm/class.go b/vm/class.go index 7a683b71a..6e0067cdb 100644 --- a/vm/class.go +++ b/vm/class.go @@ -1536,6 +1536,18 @@ var builtinClassCommonInstanceMethods = []*BuiltinMethodObject{ }, }, + { + Name: "tap", + Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object { + if blockFrame == nil { + return t.vm.InitErrorObject(errors.InternalError, sourceLine, errors.CantYieldWithoutBlockFormat) + } + + t.builtinMethodYield(blockFrame, receiver) + + return receiver + }, + }, { Name: "thread", Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object { diff --git a/vm/object_test.go b/vm/object_test.go index 0761fb7d4..e772fe502 100644 --- a/vm/object_test.go +++ b/vm/object_test.go @@ -19,3 +19,36 @@ func TestObjectClassSuperclass(t *testing.T) { v.checkSP(t, i, 1) } } + +func TestObjectTapMethod(t *testing.T) { + tests := []struct { + input string + expected interface{} + }{ + { + ` + a = 1 + a.tap do |int| + int + 1 + end +`, 1}, + { + ` + a = 1 + b = 2 + a.tap do |int| + b = int + b + end + b +`, 3}, + } + + for i, tt := range tests { + v := initTestVM() + evaluated := v.testEval(t, tt.input, getFilename()) + VerifyExpected(t, i, evaluated, tt.expected) + v.checkCFP(t, i, 0) + v.checkSP(t, i, 1) + } +} +