Skip to content

Commit

Permalink
adding topic ($_) support for map, grep, first and each on Array (res…
Browse files Browse the repository at this point in the history
…olves issue #97)
  • Loading branch information
Stevan Little committed May 3, 2013
1 parent a64d265 commit 1f0e138
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
47 changes: 36 additions & 11 deletions src/main/scala/org/moe/runtime/nativeobjects/MoeArrayObject.scala
Expand Up @@ -76,26 +76,51 @@ class MoeArrayObject(
array.map(_.unboxToString.get).mkString(sep.unboxToString.get)
)

def map (r: MoeRuntime, f: MoeCode): MoeArrayObject = r.NativeObjects.getArray(
array.map(i => f.execute(new MoeArguments(List(i)))) : _*
)
def map (r: MoeRuntime, f: MoeCode): MoeArrayObject = {
val result = array.map({
(i) =>
f.getDeclarationEnvironment.setCurrentTopic(i)
f.execute(new MoeArguments(List(i)))
})
f.getDeclarationEnvironment.clearCurrentTopic
r.NativeObjects.getArray(result : _*)
}

def grep (r: MoeRuntime, f: MoeCode): MoeArrayObject = r.NativeObjects.getArray(
array.filter(i => f.execute(new MoeArguments(List(i))).isTrue) : _*
)
def grep (r: MoeRuntime, f: MoeCode): MoeArrayObject = {
val result = array.filter({
(i) =>
f.getDeclarationEnvironment.setCurrentTopic(i)
f.execute(new MoeArguments(List(i))).isTrue
})
f.getDeclarationEnvironment.clearCurrentTopic
r.NativeObjects.getArray(result : _*)
}

def each (r: MoeRuntime, f: MoeCode): MoeUndefObject = {
array.foreach({ i => f.execute(new MoeArguments(List(i))); ()})
array.foreach({
(i) =>
f.getDeclarationEnvironment.setCurrentTopic(i)
f.execute(new MoeArguments(List(i)))
()
})
f.getDeclarationEnvironment.clearCurrentTopic
r.NativeObjects.getUndef
}

def first (r: MoeRuntime, f: MoeCode): MoeObject = {
val result = array.dropWhile({
(i) =>
f.getDeclarationEnvironment.setCurrentTopic(i)
f.execute(new MoeArguments(List(i))).isFalse
})
f.getDeclarationEnvironment.clearCurrentTopic
result.head
}

def reduce (r: MoeRuntime, f: MoeCode, init: Option[MoeObject]): MoeObject = init match {
case Some(init_val) => array.foldLeft(init_val)({ (a, b) => f.execute(new MoeArguments(List(a, b))) })
case None => array.reduceLeft ({ (a, b) => f.execute(new MoeArguments(List(a, b))) })
}

def first (r: MoeRuntime, f: MoeCode): MoeObject =
array.dropWhile(i => f.execute(new MoeArguments(List(i))).isFalse).head
}

def max (r: MoeRuntime): MoeIntObject = r.NativeObjects.getInt(
array.map(i => i.unboxToInt.get).max
Expand Down
5 changes: 5 additions & 0 deletions t/001-literals/007-arrays.t
Expand Up @@ -61,13 +61,16 @@ use Test::More;
is(@x.join(", "), "10, 5, 3, 1", '... got the expected value from &join($sep)');

is_deeply(@x.map(-> ($x) { $x + 10 }), [ 20, 15, 13, 11 ], '... got the expected value from &map');
is_deeply(@x.map(-> { $_ + 10 }), [ 20, 15, 13, 11 ], '... got the expected value from &map using $_');

is_deeply(@x.grep(-> ($x) { ($x % 2) == 0 }), [ 10 ], '... got the expected value from &grep');
is_deeply(@x.grep(-> { ($_ % 2) == 0 }), [ 10 ], '... got the expected value from &grep using $_');

is(@x.reduce(-> ($a, $b) { $a + $b }), 19, '... got the exepected value from &reduce');
is(@x.reduce(-> ($a, $b) { $a + $b }, 100), 119, '... got the exepected value from &reduce($init)');

is(@x.first(-> ($x) { $x > 5 }), 10, '... got the exepected value from &first');
is(@x.first(-> { $_ > 5 }), 10, '... got the exepected value from &first using $_');

is(@x.max, 10, '... got the exepected value from &max');
is(@x.min, 1, '... got the exepected value from &min');
Expand All @@ -91,6 +94,8 @@ use Test::More;
my @x = [ 'foo', 'bar', 'baz' ];
is(@x.each(-> ($x) { $x.chop }), undef, '... got the exepected value from &each');
is_deeply(@x, [ 'fo', 'ba', 'ba' ], '... the array has been changed');
is(@x.each(-> { $_.chop }), undef, '... got the exepected value from &each using $_');
is_deeply(@x, [ 'f', 'b', 'b' ], '... the array has been changed');
}

{
Expand Down

2 comments on commit 1f0e138

@prakashk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is setting $_ in addition to the variable specified in the signature. Perl6 sets the topic variable $_, only if no signature was specified.

Moe:

moe> [1,2,3].map(-> {$_ + 1})
[2, 3, 4]
moe> [1,2,3].map(-> ($x) {$x + 1})
[2, 3, 4]
moe> [1,2,3].map(-> ($x) {$x + $_})
[2, 4, 6]

Perl6:

>> perl6 -v
This is perl6 version 2012.12 built on parrot 4.10.0 revision 0

>> perl6
> (1,2,3).map: { $_ + 1 }
2 3 4
> (1,2,3).map: -> $x { $x + 1 }
2 3 4
> (1,2,3).map: -> $x { $x + $_ }
use of uninitialized variable $_ of type Any in numeric context
use of uninitialized variable $_ of type Any in numeric context
use of uninitialized variable $_ of type Any in numeric context
1 2 3

@stevan
Copy link
Member

@stevan stevan commented on 1f0e138 May 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@prakashk I thought about that, I am not sure how I feel about it. I will need to give it some thought. That said it is easy to add in later.

Please sign in to comment.