# Experimentation

**URL:** <https://www.ruby-forum.com/t/experimentation/117167>\
**Category:** IronRuby\
**Created:** [October 14, 2007, 5:16am UTC](https://www.ruby-forum.com/t/experimentation/117167 "2007-10-14T05:16:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 5:16am UTC](https://www.ruby-forum.com/t/experimentation/117167/1 "2007-10-14T05:16:22Z")

</div>

I thought I’d implement some missing members on the String class in  
order to  
get my feet wet and start to understand the software. I chose  
String.scanon the grounds that it was a fairly common function  
(between 20 and 30  
references in the standard library) with straightforward semantics, but  
one  
which requires dealing with overloads and blocks.

There are basically four variations of this function:  
String.scan   
String.scan   
String.scan ,   
String.scan ,

I’ve attempted to implement each of these, and believe that all but the  
last  
are correct. The variations are implemented in two different  
flavors for both CLR strings and mutable strings. A patch can be found  
at  
[http://hagenlocher.org/software/MutableString.scan.patch.txt](http://hagenlocher.org/software/MutableString.scan.patch.txt)

The two issues I ran into are as follows:

1. The overload mechanism is picking the wrong method at runtime. Here  
are  
two of the function prototypes:

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static List Scan(MutableString/_!_/ self,  
MutableString/_!_/  
searchStr)  
[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self,  
MutableString searchStr, BlockParam block)

When I run from rbx.exe, I get the following:

> > > “hello world”.scan(“l”)  
> > > =\> [“l”, “l”, “l”]  
> > > “hello world”.scan(“l”) {|x| print x}  
> > > =\> [“l”, “l”, “l”]

In contrast, CRuby gives this:  
irb(main):001:0\> “hello world”.scan(“l”)  
=\> [“l”, “l”, “l”]  
irb(main):002:0\> “hello world”.scan(“l”) {|x| print x}  
lll=\> “hello world”

Am I doing something wrong, or is this a bug? (I have obviously updated  
Initializer.Generated.cs, or neither scan would have been found :).

1. My implementation of String.scan , is incomplete.  
This  
function is defined to behave as follows:  
a.scan(/\w+/) {|w| print "\<\<#{w}\>\> " }  
a.scan(/(.)(.)/) {|x,y| print y, x }

In other words, the number of parameters being passed to the block is  
equal  
to the number of groups defined in the regular expression – or 1 if  
there  
are no groups defined. I haven’t been able to find way to pass  
parameters  
or define a call site or that would support this.

Finally, it’s a bit annoying to rebuild Initializer.Generated.cs.  
Whenever  
you change a method signature, you have to manually delete the  
appropriate  
part of the old file in order to regenerate it, or you’ll get an error.  
I’ve made an empty version of that source file and a batch file that  
copies  
it on top of the previous version before rebuilding ClassInitGenerator.  
Assuming that the architecture is going to be here for a while, it would  
be  
nice if there were a target in the Rakefile that performed these steps.

After a few more hours of this, I may have to figure out how to do that  
myself. 🙂

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 8:00am UTC](https://www.ruby-forum.com/t/experimentation/117167/2 "2007-10-14T08:00:32Z")

</div>

1. 

```
 Change the signatures to:
 [RubyMethodAttribute("scan", 

```

RubyMethodAttributes.PublicInstance)]  
public static List/_!_/ Scan(MutableString/_!_/ self,  
[NotNull]MutableString/_!_/ searchStr)

```
    [RubyMethodAttribute("scan", 

```

RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context,  
MutableString/_!_/ self, [NotNull]BlockParam/_!_/ block,  
[NotNull]MutableString/_!_/ searchStr)

a) Block is a special parameter and it must follow self parameter.  
The order of parameters is:

- 

```
    context

```

- 

```
    self

```

- 

```
    block

```

- 

```
    mandatory parameters

```

- 

```
    optional parameters

```

- 

```
    params array (rest parameters)

```

b) Specify [NotNull] for parameters that cannot be null in order to  
select the overload. You can assume that parameters doesn’t have null  
value when called from a DLR language. It’s not a CLR attribute though  
so it doesn’t prevent a non-dynamic languages to pass null. Since the  
library methods are not supposed to be called directly (only Ruby  
runtime should invoke the method), you don’t need to check for  
non-nullity at runtime. Context parameter is always non-null (no need to  
check for null at run-time). Self parameter is also non-null unless the  
method is a module method or an instance method of NilClass.

c) Annotate types by /_!_/ annotation if you assume them to be  
non-null. Although the annotation doesn’t affect run-time behavior at  
all (being a comment, it’s ignored by C#) it is useful for static  
analysis and expresses your assumptions.

d) Note also that unless marked by NotNull attribute, BlockParam is  
nullable. Hence the overload might be eligible for invocation even  
though no block has been passed. A null reference is used if the block  
is not specified in a call site and there is no overload that matches  
better. So a single overload with BlockParam parameter also works. It  
depends on the semantics of the method which variant to chose. If  
presence of the block significantly changes the behavior of the method  
then it’s probably better to have two overloads. Code like  
[RubyMethod(“foo”)]public static Foo(… block …) { if (block != null)  
{ 1st overload implementation } else { 2nd overload implementation} }  
should be avoided if possible; two overloads should be defined instead.  
On the other hand, if the implementation almost doesn’t depend on  
whether the block is present or not (it only affects a small part of the  
implementation) then it’s probably better to have a single overload.

1. 

```
 Check out dynamic site in Thread.CreateThread. It should do what 

```

you need. The magic is in ArgumentKind.List (splat).

1. 

```
 Feel free to patch the Rakefile. Note however, that we are going 

```

to change the shape of libraries a little bit (in particular move  
Builtins to IronRuby.Libraries.dll), so it might be necessary to adjust  
the script again afterwards.

Note that MutableString has an instance method IndexOf, so you don’t  
need to convert to a CLR string (the method internally makes the  
conversion but that’s only provisional implementation).

Tomas

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: Saturday, October 13, 2007 8:16 PM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] Experimentation

I thought I’d implement some missing members on the String class in  
order to get my feet wet and start to understand the software. I chose  
String.scan on the grounds that it was a fairly common function (between  
20 and 30 references in the standard library) with straightforward  
semantics, but one which requires dealing with overloads and blocks.

There are basically four variations of this function:  
String.scan   
String.scan   
String.scan ,   
String.scan ,

I’ve attempted to implement each of these, and believe that all but the  
last are correct. The variations are implemented in two  
different flavors for both CLR strings and mutable strings. A patch can  
be found at [http://hagenlocher.org/software/MutableString.scan.patch.txt](http://hagenlocher.org/software/MutableString.scan.patch.txt)

The two issues I ran into are as follows:

1. The overload mechanism is picking the wrong method at runtime. Here  
are two of the function prototypes:

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static List Scan(MutableString/_!_/ self,  
MutableString/_!_/ searchStr)  
[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block)

When I run from rbx.exe, I get the following:

> > > “hello world”.scan(“l”)  
> > > =\> [“l”, “l”, “l”]  
> > > “hello world”.scan(“l”) {|x| print x}  
> > > =\> [“l”, “l”, “l”]

In contrast, CRuby gives this:  
irb(main):001:0\> “hello world”.scan(“l”)  
=\> [“l”, “l”, “l”]  
irb(main):002:0\> “hello world”.scan(“l”) {|x| print x}  
lll=\> “hello world”

Am I doing something wrong, or is this a bug? (I have obviously updated  
Initializer.Generated.cs, or neither scan would have been found :).

1. My implementation of String.scan , is incomplete.  
This function is defined to behave as follows:  
a.scan(/\w+/) {|w| print "\<\<#{w}\>\> " }  
a.scan(/(.)(.)/) {|x,y| print y, x }

In other words, the number of parameters being passed to the block is  
equal to the number of groups defined in the regular expression – or 1  
if there are no groups defined. I haven’t been able to find way to pass  
parameters or define a call site or that would support this.

Finally, it’s a bit annoying to rebuild Initializer.Generated.cs.  
Whenever you change a method signature, you have to manually delete the  
appropriate part of the old file in order to regenerate it, or you’ll  
get an error. I’ve made an empty version of that source file and a  
batch file that copies it on top of the previous version before  
rebuilding ClassInitGenerator. Assuming that the architecture is going  
to be here for a while, it would be nice if there were a target in the  
Rakefile that performed these steps.

After a few more hours of this, I may have to figure out how to do that  
myself. 🙂

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 8:21am UTC](https://www.ruby-forum.com/t/experimentation/117167/3 "2007-10-14T08:21:34Z")

</div>

Whoops, looks like emails crossed. I think Tomas is right-- we’re not  
picking the block overload because the block parameter needs to be after  
self, not at the end like you might expect. Well, it’s worth trying to  
see if that fixes the problem 🙂

Cheers,  
John

From: John M.  
Sent: Saturday, October 13, 2007 11:14 PM  
To: removed\_email\_address@domain.invalid  
Subject: RE: [Ironruby-core] Experimentation

Hi Curt,

Sounds like a method binder bug. The workaround is to merge the two  
methods into one:

[RubyMethod(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block) {  
if (block == null) {  
// block wasn’t supplied  
} else {  
// …  
}  
}

Even though a “BlockParam” argument is present, you can still call the  
method w/o a block. (Essentially, all “BlockParams” are [Optional])  
In the meantime, I’ll see if I can figure out why the binder is picking  
the wrong overload.

- John

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: Saturday, October 13, 2007 8:16 PM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] Experimentation

I thought I’d implement some missing members on the String class in  
order to get my feet wet and start to understand the software. I chose  
String.scan on the grounds that it was a fairly common function (between  
20 and 30 references in the standard library) with straightforward  
semantics, but one which requires dealing with overloads and blocks.

There are basically four variations of this function:  
String.scan   
String.scan   
String.scan ,   
String.scan ,

I’ve attempted to implement each of these, and believe that all but the  
last are correct. The variations are implemented in two  
different flavors for both CLR strings and mutable strings. A patch can  
be found at [http://hagenlocher.org/software/MutableString.scan.patch.txt](http://hagenlocher.org/software/MutableString.scan.patch.txt)

The two issues I ran into are as follows:

1. The overload mechanism is picking the wrong method at runtime. Here  
are two of the function prototypes:

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static List Scan(MutableString/_!_/ self,  
MutableString/_!_/ searchStr)  
[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block)

When I run from rbx.exe, I get the following:

> > > “hello world”.scan(“l”)  
> > > =\> [“l”, “l”, “l”]  
> > > “hello world”.scan(“l”) {|x| print x}  
> > > =\> [“l”, “l”, “l”]

In contrast, CRuby gives this:  
irb(main):001:0\> “hello world”.scan(“l”)  
=\> [“l”, “l”, “l”]  
irb(main):002:0\> “hello world”.scan(“l”) {|x| print x}  
lll=\> “hello world”

Am I doing something wrong, or is this a bug? (I have obviously updated  
Initializer.Generated.cs, or neither scan would have been found :).

1. My implementation of String.scan , is incomplete.  
This function is defined to behave as follows:  
a.scan(/\w+/) {|w| print "\<\<#{w}\>\> " }  
a.scan(/(.)(.)/) {|x,y| print y, x }

In other words, the number of parameters being passed to the block is  
equal to the number of groups defined in the regular expression – or 1  
if there are no groups defined. I haven’t been able to find way to pass  
parameters or define a call site or that would support this.

Finally, it’s a bit annoying to rebuild Initializer.Generated.cs.  
Whenever you change a method signature, you have to manually delete the  
appropriate part of the old file in order to regenerate it, or you’ll  
get an error. I’ve made an empty version of that source file and a  
batch file that copies it on top of the previous version before  
rebuilding ClassInitGenerator. Assuming that the architecture is going  
to be here for a while, it would be nice if there were a target in the  
Rakefile that performed these steps.

After a few more hours of this, I may have to figure out how to do that  
myself. 🙂

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 3:52pm UTC](https://www.ruby-forum.com/t/experimentation/117167/4 "2007-10-14T15:52:46Z")

</div>

Thanks for all of the excellent advice; everything is now working. I  
had  
guessed there might be an issue on the overload with the specific  
signature  
of the function, but I wasn’t able to find any examples of existing code  
that contradicted what I had done. Now that I know what to look for, of  
course… :). I wonder if it wouldn’t be a good idea for the  
ClassInitGenerator to emit a warning when there’s a signature containing  
a  
BlockParam that doesn’t follow the correct pattern.

The /_!_/ annotation seems a bit redundant with [NotNull], doesn’t it? I  
think I’m just resentful that it’s a bunch of characters that totally  
interrupt the flow of my typing. 😛

I considered merging the block form of the scan function with the  
blockless  
form, but it seemed that the result would be considerably harder to read  
and  
understand than keeping them seperate.

Is this the sort of change you’d like to see submitted to the project?  
If  
so, I’ll write some tests (I know; should have done it the other way  
around)  
and generate another patch file.

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 8:19am UTC](https://www.ruby-forum.com/t/experimentation/117167/5 "2007-10-14T08:19:49Z")

</div>

Hi Curt,

Sounds like a method binder bug. The workaround is to merge the two  
methods into one:

[RubyMethod(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block) {  
if (block == null) {  
// block wasn’t supplied  
} else {  
// …  
}  
}

Even though a “BlockParam” argument is present, you can still call the  
method w/o a block. (Essentially, all “BlockParams” are [Optional])  
In the meantime, I’ll see if I can figure out why the binder is picking  
the wrong overload.

- John

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: Saturday, October 13, 2007 8:16 PM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] Experimentation

I thought I’d implement some missing members on the String class in  
order to get my feet wet and start to understand the software. I chose  
String.scan on the grounds that it was a fairly common function (between  
20 and 30 references in the standard library) with straightforward  
semantics, but one which requires dealing with overloads and blocks.

There are basically four variations of this function:  
String.scan   
String.scan   
String.scan ,   
String.scan ,

I’ve attempted to implement each of these, and believe that all but the  
last are correct. The variations are implemented in two  
different flavors for both CLR strings and mutable strings. A patch can  
be found at [http://hagenlocher.org/software/MutableString.scan.patch.txt](http://hagenlocher.org/software/MutableString.scan.patch.txt)

The two issues I ran into are as follows:

1. The overload mechanism is picking the wrong method at runtime. Here  
are two of the function prototypes:

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static List Scan(MutableString/_!_/ self,  
MutableString/_!_/ searchStr)  
[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block)

When I run from rbx.exe, I get the following:

> > > “hello world”.scan(“l”)  
> > > =\> [“l”, “l”, “l”]  
> > > “hello world”.scan(“l”) {|x| print x}  
> > > =\> [“l”, “l”, “l”]

In contrast, CRuby gives this:  
irb(main):001:0\> “hello world”.scan(“l”)  
=\> [“l”, “l”, “l”]  
irb(main):002:0\> “hello world”.scan(“l”) {|x| print x}  
lll=\> “hello world”

Am I doing something wrong, or is this a bug? (I have obviously updated  
Initializer.Generated.cs, or neither scan would have been found :).

1. My implementation of String.scan , is incomplete.  
This function is defined to behave as follows:  
a.scan(/\w+/) {|w| print "\<\<#{w}\>\> " }  
a.scan(/(.)(.)/) {|x,y| print y, x }

In other words, the number of parameters being passed to the block is  
equal to the number of groups defined in the regular expression – or 1  
if there are no groups defined. I haven’t been able to find way to pass  
parameters or define a call site or that would support this.

Finally, it’s a bit annoying to rebuild Initializer.Generated.cs.  
Whenever you change a method signature, you have to manually delete the  
appropriate part of the old file in order to regenerate it, or you’ll  
get an error. I’ve made an empty version of that source file and a  
batch file that copies it on top of the previous version before  
rebuilding ClassInitGenerator. Assuming that the architecture is going  
to be here for a while, it would be nice if there were a target in the  
Rakefile that performed these steps.

After a few more hours of this, I may have to figure out how to do that  
myself. 🙂

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 10:10pm UTC](https://www.ruby-forum.com/t/experimentation/117167/6 "2007-10-14T22:10:48Z")

</div>

On 10/14/07, Tomas M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Yes, you’re right it seems redundant but unfortunately it’s not. The  
> problem is that our (i.e. DLR’s) NotNull attribute is currently not  
> understood by Spec# (static verifier). It’s only influencing the overload  
> resolution, nothing else. So Spec# would complain that you’re e.g.  
> “dotting thru” a variable that might be null.

Ah, I didn’t realize there was a program looking directly at the source  
code.

> If you can define a macro in your favorite text editor, this is the  
> right use of that feature.

🙂

> Yes, we accept contributions to libraries, i.e. to  
> IronRuby.Libraries.dll. Although MutableString class will stay where it  
> is, Ruby method implementations for MutableString will soon get factored out  
> to the Libraries assembly. Hence we could take your contribution then if it  
> will be correct and efficient.

I see that the operations have now been factored out into  
MutableStringOps.cs, presumably in preparation for this migration. If  
it’s  
not premature, there’s an updated patch file (is that the preferred  
format?)  
at [http://hagenlocher.org/software/MutableStringOps.scan.patch.txt](http://hagenlocher.org/software/MutableStringOps.scan.patch.txt) which  
incorporates implementations for scan, upto, swapcase and swapcase!, as  
well  
as tests for all of these changes in test.string.rb.

These days, i18n is at the top of my brain as my company works on  
internationalizing its product. It’s charmingly quaint to see that  
IronRuby  
(and presumably Ruby) have explicit tests against the ranges ‘A’-‘Z’ and  
‘a’-‘z’ for purposes of checking and changing the case of individual  
letters  
:).

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 6:23pm UTC](https://www.ruby-forum.com/t/experimentation/117167/7 "2007-10-14T18:23:03Z")

</div>

Inline.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: Sunday, October 14, 2007 6:52 AM  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] Experimentation

Thanks for all of the excellent advice; everything is now working. I  
had guessed there might be an issue on the overload with the specific  
signature of the function, but I wasn’t able to find any examples of  
existing code that contradicted what I had done. Now that I know what  
to look for, of course… :). I wonder if it wouldn’t be a good idea  
for the ClassInitGenerator to emit a warning when there’s a signature  
containing a BlockParam that doesn’t follow the correct pattern.

Yes, that’s the plan - CIG will check for other errors as well.

The /_!_/ annotation seems a bit redundant with [NotNull], doesn’t it? I  
think I’m just resentful that it’s a bunch of characters that totally  
interrupt the flow of my typing. 😛

Yes, you’re right it seems redundant but unfortunately it’s not. The  
problem is that our (i.e. DLR’s) NotNull attribute is currently not  
understood by Spec# (static verifier). It’s only influencing the  
overload resolution, nothing else. So Spec# would complain that you’re  
e.g. “dotting thru” a variable that might be null.

If you can define a macro in your favorite text editor, this is the  
right use of that feature.

I considered merging the block form of the scan function with the  
blockless form, but it seemed that the result would be considerably  
harder to read and understand than keeping them seperate.

Is this the sort of change you’d like to see submitted to the project?  
If so, I’ll write some tests (I know; should have done it the other way  
around) and generate another patch file.

Yes, we accept contributions to libraries, i.e. to  
IronRuby.Libraries.dll. Although MutableString class will stay where it  
is, Ruby method implementations for MutableString will soon get factored  
out to the Libraries assembly. Hence we could take your contribution  
then if it will be correct and efficient.

Tomas

On 10/13/07, Tomas M.  
\<removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)\>  
wrote:

1. 

```
 Change the signatures to:

 [RubyMethodAttribute("scan", 

```

RubyMethodAttributes.PublicInstance)]

```
    public static List<object> /*!*/ Scan(MutableString/*!*/ self, 

```

[NotNull]MutableString /_!_/ searchStr)

```
    [RubyMethodAttribute("scan", 

```

RubyMethodAttributes.PublicInstance)]

```
    public static object Scan(CodeContext /*!*/ context, 

```

MutableString/_!_/ self, [NotNull]BlockParam /_!_/ block,  
[NotNull]MutableString/_!_/ searchStr)

a) Block is a special parameter and it must follow self parameter.  
The order of parameters is:

- 

```
    context

```

- 

```
    self

```

- 

```
    block

```

- 

```
    mandatory parameters

```

- 

```
    optional parameters

```

- 

```
    params array (rest parameters)

```

b) Specify [NotNull] for parameters that cannot be null in order to  
select the overload. You can assume that parameters doesn’t have null  
value when called from a DLR language. It’s not a CLR attribute though  
so it doesn’t prevent a non-dynamic languages to pass null. Since the  
library methods are not supposed to be called directly (only Ruby  
runtime should invoke the method), you don’t need to check for  
non-nullity at runtime. Context parameter is always non-null (no need to  
check for null at run-time). Self parameter is also non-null unless the  
method is a module method or an instance method of NilClass.

c) Annotate types by /_!_/ annotation if you assume them to be  
non-null. Although the annotation doesn’t affect run-time behavior at  
all (being a comment, it’s ignored by C#) it is useful for static  
analysis and expresses your assumptions.

d) Note also that unless marked by NotNull attribute, BlockParam is  
nullable. Hence the overload might be eligible for invocation even  
though no block has been passed. A null reference is used if the block  
is not specified in a call site and there is no overload that matches  
better. So a single overload with BlockParam parameter also works. It  
depends on the semantics of the method which variant to chose. If  
presence of the block significantly changes the behavior of the method  
then it’s probably better to have two overloads. Code like  
[RubyMethod(“foo”)]public static Foo(… block …) { if (block != null)  
{ 1 st overload implementation } else { 2nd overload implementation} }  
should be avoided if possible; two overloads should be defined instead.  
On the other hand, if the implementation almost doesn’t depend on  
whether the block is present or not (it only affects a small part of the  
implementation) then it’s probably better to have a single overload.

1. 

```
 Check out dynamic site in Thread.CreateThread. It should do what 

```

you need. The magic is in ArgumentKind.List (splat).

1. 

```
 Feel free to patch the Rakefile. Note however, that we are going 

```

to change the shape of libraries a little bit (in particular move  
Builtins to IronRuby.Libraries.dll), so it might be necessary to adjust  
the script again afterwards.

Note that MutableString has an instance method IndexOf, so you don’t  
need to convert to a CLR string (the method internally makes the  
conversion but that’s only provisional implementation).

Tomas

From: removed\_email\_address@domain.invalid  
[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
On Behalf Of Curt H.  
Sent: Saturday, October 13, 2007 8:16 PM  
To: removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Subject: [Ironruby-core] Experimentation

I thought I’d implement some missing members on the String class in  
order to get my feet wet and start to understand the software. I chose  
String.scan on the grounds that it was a fairly common function (between  
20 and 30 references in the standard library) with straightforward  
semantics, but one which requires dealing with overloads and blocks.

There are basically four variations of this function:  
String.scan   
String.scan   
String.scan ,   
String.scan ,

I’ve attempted to implement each of these, and believe that all but the  
last are correct. The variations are implemented in two  
different flavors for both CLR strings and mutable strings. A patch can  
be found at [http://hagenlocher.org/software/MutableString.scan.patch.txt](http://hagenlocher.org/software/MutableString.scan.patch.txt)

The two issues I ran into are as follows:

1. The overload mechanism is picking the wrong method at runtime. Here  
are two of the function prototypes:

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static List Scan(MutableString/_!_/ self,  
MutableString/_!_/ searchStr)

[RubyMethodAttribute(“scan”, RubyMethodAttributes.PublicInstance)]  
public static object Scan(CodeContext/_!_/ context, MutableString/_!_/  
self, MutableString searchStr, BlockParam block)

When I run from rbx.exe, I get the following:

> > > “hello world”.scan(“l”)  
> > > =\> [“l”, “l”, “l”]

> > > “hello world”.scan(“l”) {|x| print x}  
> > > =\> [“l”, “l”, “l”]

In contrast, CRuby gives this:

irb(main):001:0\> “hello world”.scan(“l”)  
=\> [“l”, “l”, “l”]  
irb(main):002:0\> “hello world”.scan(“l”) {|x| print x}  
lll=\> “hello world”

Am I doing something wrong, or is this a bug? (I have obviously updated  
Initializer.Generated.cs, or neither scan would have been found :).

1. My implementation of String.scan , is incomplete.  
This function is defined to behave as follows:

In other words, the number of parameters being passed to the block is  
equal to the number of groups defined in the regular expression – or 1  
if there are no groups defined. I haven’t been able to find way to pass  
parameters or define a call site or that would support this.

Finally, it’s a bit annoying to rebuild Initializer.Generated.cs.  
Whenever you change a method signature, you have to manually delete the  
appropriate part of the old file in order to regenerate it, or you’ll  
get an error. I’ve made an empty version of that source file and a  
batch file that copies it on top of the previous version before  
rebuilding ClassInitGenerator. Assuming that the architecture is going  
to be here for a while, it would be nice if there were a target in the  
Rakefile that performed these steps.

After a few more hours of this, I may have to figure out how to do that  
myself. 🙂

–

Curt H.

removed\_email\_address@domain.invalid[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![curthibbs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/ac91a4/32.png) [@curthibbs](https://www.ruby-forum.com/u/curthibbs)\
**Post date:** [October 14, 2007, 11:56pm UTC](https://www.ruby-forum.com/t/experimentation/117167/8 "2007-10-14T23:56:08Z")

</div>

On 10/14/07, Curt H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> If it’s not premature, there’s an updated patch file (is that the  
> preferred format?) at  
> [http://hagenlocher.org/software/MutableStringOps.scan.patch.txt](http://hagenlocher.org/software/MutableStringOps.scan.patch.txt) which  
> incorporates implementations for scan, upto, swapcase and swapcase!, as well  
> as tests for all of these changes in test.string.rb.

Proving that “you can’t eat just one”, I’ve amended this to include  
center,  
chomp, chomp!, chop and chop!. And they say that watching television  
isn’t  
productive…
