From 98fdc39a16e115b99145f11f683d4892385268d9 Mon Sep 17 00:00:00 2001 From: trizen Date: Thu, 5 Mar 2020 22:28:20 +0200 Subject: [PATCH] - Allow prefix method-calls in class `has` variables. This fixes code like: class Example (value) { has t = sqrt(value) } var obj = Example(42) say obj.t Previously, the above code incorrectly died with a run-time error. --- MANIFEST | 1 + lib/Sidef/Parser.pm | 2 +- ...class_has_variables_with_prefix_methods.sf | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 scripts/Tests/class_has_variables_with_prefix_methods.sf diff --git a/MANIFEST b/MANIFEST index d1783485b..38d50aaf4 100644 --- a/MANIFEST +++ b/MANIFEST @@ -685,6 +685,7 @@ scripts/Tests/class_attr_inheritance.sf scripts/Tests/class_attributes.sf scripts/Tests/class_field_inheritance.sf scripts/Tests/class_global_variables.sf +scripts/Tests/class_has_variables_with_prefix_methods.sf scripts/Tests/class_inheritance.sf scripts/Tests/class_inside_module.sf scripts/Tests/class_redefinition.sf diff --git a/lib/Sidef/Parser.pm b/lib/Sidef/Parser.pm index 1a3570efe..41e6becd7 100644 --- a/lib/Sidef/Parser.pm +++ b/lib/Sidef/Parser.pm @@ -1194,7 +1194,7 @@ package Sidef::Parser { # "has" class attributes if (exists($self->{current_class}) and /\Ghas\b\h*/gc) { - local $self->{allow_class_variable} = 1; + local $self->{allow_class_variable} = 0; my $vars = $self->parse_init_vars( code => $opt{code}, diff --git a/scripts/Tests/class_has_variables_with_prefix_methods.sf b/scripts/Tests/class_has_variables_with_prefix_methods.sf new file mode 100644 index 000000000..902ed8a32 --- /dev/null +++ b/scripts/Tests/class_has_variables_with_prefix_methods.sf @@ -0,0 +1,69 @@ +#!/usr/bin/ruby + +class Friend(name) { + method hi { + "Hello, #{name}!" + } +} + +class Example(a) { + has t = sqrt(a) + + has v = try { Friend("Agent #{a}") } catch { 'undefined' } + has u = try { NotDefined("foo #{a}") } catch { 'undefined' } + + has w = Friend("Actor #{a + 1}") + + method foo { + self.bar + } + + method bar { + log(t) + } + + method baz(tmp = sqrt(2)) { + tmp + 1 + } + + method qux(z = t) { + z + 1 + } + + method zoo(r = self.t) { + r - 1 + } + + method zzz(f = self.bar) { + f + 1 + } + + method friend { + v.name + } +} + +var obj = Example(99) + +assert_eq(obj.t, 99.sqrt) +assert_eq(obj.bar, 99.sqrt.log) +assert_eq(obj.baz, 2.sqrt + 1) +assert_eq(obj.qux, 99.sqrt + 1) +assert_eq(obj.zoo, 99.sqrt - 1) +assert_eq(obj.zzz, 99.sqrt.log + 1) + +assert_eq(obj.friend, "Agent 99") +assert_eq(obj.v.hi, "Hello, Agent 99!") +assert_eq(obj.w.hi, "Hello, Actor 100!") + +obj.t = 1234 + +assert_eq(obj.v.hi, "Hello, Agent 99!") +assert_eq(Example(7).v.hi, "Hello, Agent 7!") + +assert_eq(obj.v.hi, "Hello, Agent 99!") +assert_eq(obj.w.hi, "Hello, Actor 100!") + +assert_eq(obj.u, 'undefined') + +say "** Test passed!"