<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman, new york, times, serif;font-size:12pt"><DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Hi Peter,</DIV>
<DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Fantastic point, now that I am understanding the code, it makes perfect sense, I really appriciate the comments.</DIV>
<DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Thanks.<BR><BR></DIV>
<DIV style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">----- Original Message ----<BR>From: Peter Bacon Darwin &lt;bacondarwin@googlemail.com&gt;<BR>To: ironruby-core@rubyforge.org<BR>Sent: Sunday, May 11, 2008 7:14:48 AM<BR>Subject: Re: [Ironruby-core] RubyForge bug fixes<BR><BR>
<STYLE>
<!--
 _filtered {font-family:Wingdings;panose-1:5 0 0 0 0 0 0 0 0 0;}
 _filtered {font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;}
 _filtered {font-family:Calibri;panose-1:2 15 5 2 2 2 4 3 2 4;}
 _filtered {font-family:Tahoma;panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;margin-bottom:.0001pt;font-size:12.0pt;font-family:"Times New Roman", "serif";}
a:link, span.MsoHyperlink
        {color:blue;text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {color:purple;text-decoration:underline;}
p
        {margin-right:0in;margin-left:0in;font-size:12.0pt;font-family:"Times New Roman", "serif";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {margin-top:0in;margin-right:0in;margin-bottom:0in;margin-left:.5in;margin-bottom:.0001pt;font-size:12.0pt;font-family:"Times New Roman", "serif";}
span.EmailStyle18
        {font-family:"Calibri", "sans-serif";color:#1F497D;}
.MsoChpDefault
        {font-size:10.0pt;}
 _filtered {margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {}
 _filtered {}
 _filtered {font-family:Symbol;}
 _filtered {font-family:"Courier New";}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
-->
</STYLE>

<DIV class=Section1>
<P class=MsoNormal><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">Hi Unnikrishnan,</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">Just a couple of points you might find useful:</SPAN></P>
<P class=MsoListParagraph><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Symbol"><SPAN>·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">A number of overloads have parameters like ..., object/*!*/ path, ... What you are saying to the Specsharp tool is that object should never be null.&nbsp; Is this what you want?&nbsp; Can you pass nil into the methods in MRI?&nbsp; If you can then you need to remove the /*!*/.&nbsp; If you canąt then you probably need to add [NotNull] attribute or handle the case where the parameter is null within you method.&nbsp; Since you usually pass the value into CastToString, which handles the null case then probably removing the /*!*/ is what is required.</SPAN></P>
<P class=MsoListParagraph><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Symbol"><SPAN>·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">In Public Singleton methods I believe you can guarantee that the self parameter that gets passed in is actually the class that owns the method and so you can type this parameter to RubyClass/*!*/ if you want.&nbsp; Since the class is not being used in these methods it is not important, but it can save you a cast in other methods.</SPAN></P>
<P class=MsoListParagraph><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Symbol"><SPAN>·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">In some of the overloads you are using the Ruby regex classes.&nbsp; Do you know if MRI uses these and if so do they call the methods on them directly or via the Ruby method invocation process?&nbsp; If the latter then you need to use Dynamic Invocation to call the methods in your overloads [so that if someone monkey patches the Regex classes the behaviour shows up in the File class].&nbsp; I suspect this is not the case but worth writing an RSpec for to check.</SPAN></P>
<P class=MsoListParagraph><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: Symbol"><SPAN>·<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">It might be worth pulling the MutableString objects that you use for comparison out into static readonly variables so that you donąt have to keep instantiating them every call.&nbsp; Such as:<BR>private static readonly MutableString dotStar = MutableString.Create(".*"); and<BR>private static readonly MutableString empty = MutableString.CreateEmpty();<BR><BR></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">Hope that helps.</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">Pete</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri', 'sans-serif'">&nbsp;</SPAN></P>
<DIV>
<DIV style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0in; BORDER-TOP: #b5c4df 1pt solid; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; BORDER-LEFT: medium none; PADDING-TOP: 3pt; BORDER-BOTTOM: medium none">
<P class=MsoNormal><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Tahoma', 'sans-serif'">From:</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Tahoma', 'sans-serif'"> ironruby-core-bounces@rubyforge.org [mailto:ironruby-core-bounces@rubyforge.org] <B>On Behalf Of </B>Unnikrishnan Nair<BR><B>Sent:</B> Saturday,10 May 10, 2008 22:59<BR><B>To:</B> ironruby-core@rubyforge.org<BR><B>Subject:</B> Re: [Ironruby-core] RubyForge bug fixes</SPAN></P></DIV></DIV>
<P class=MsoNormal>&nbsp;</P>
<DIV>
<P>Hi John,</P>
<P>&nbsp;</P>
<P><SPAN style="FONT-SIZE: 10pt">Here is my code that I have, this is the first method I attemepted since this is one of the interesting logic. I thought I post my code for you to review as well. This passed most of the test as well</SPAN></P>
<P>&nbsp;</P>
<P><SPAN style="FONT-SIZE: 10pt">[<SPAN style="COLOR: #2b91af">RubyMethod</SPAN>(<SPAN style="COLOR: #a31515">"basename"</SPAN>, <SPAN style="COLOR: #2b91af">RubyMethodAttributes</SPAN>.PublicSingleton)]</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">public</SPAN><SPAN style="FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: #2b91af">MutableString</SPAN> Basename(<SPAN style="COLOR: #2b91af">CodeContext</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> context, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> self, [<SPAN style="COLOR: #2b91af">NotNull</SPAN>]<SPAN style="COLOR: #2b91af">MutableString</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> path)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: #2b91af">MutableString</SPAN><SPAN style="FONT-SIZE: 10pt">[] tokens = path.Split(<SPAN style="COLOR: #a31515">@"\/"</SPAN>.ToCharArray(), <SPAN style="COLOR: #2b91af">Int32</SPAN>.MaxValue, <SPAN style="COLOR: #2b91af">StringSplitOptions</SPAN>.RemoveEmptyEntries);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: #2b91af">MutableString</SPAN><SPAN style="FONT-SIZE: 10pt"> returnString = (tokens.GetLength(0) &gt; 0) ? tokens[tokens.GetLength(0) - 1] : path; </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">if</SPAN><SPAN style="FONT-SIZE: 10pt"> ((tokens.GetLength(0) &gt; 0) &amp;&amp; (returnString.GetChar(returnString.Length - 1).Equals(<SPAN style="COLOR: #a31515">':'</SPAN>)))</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">returnString = path;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">return</SPAN><SPAN style="FONT-SIZE: 10pt"> returnString;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">[<SPAN style="COLOR: #2b91af">RubyMethod</SPAN>(<SPAN style="COLOR: #a31515">"basename"</SPAN>, <SPAN style="COLOR: #2b91af">RubyMethodAttributes</SPAN>.PublicSingleton)]</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">public</SPAN><SPAN style="FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: #2b91af">MutableString</SPAN> Basename(<SPAN style="COLOR: #2b91af">CodeContext</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> context, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> self, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> path)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">return</SPAN><SPAN style="FONT-SIZE: 10pt"> Basename(context, self, <SPAN style="COLOR: #2b91af">Protocols</SPAN>.CastToString(context, path));</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">[<SPAN style="COLOR: #2b91af">RubyMethod</SPAN>(<SPAN style="COLOR: #a31515">"basename"</SPAN>, <SPAN style="COLOR: #2b91af">RubyMethodAttributes</SPAN>.PublicSingleton)]</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">public</SPAN><SPAN style="FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: #2b91af">MutableString</SPAN> Basename(<SPAN style="COLOR: #2b91af">CodeContext</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> context, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> self, [<SPAN style="COLOR: #2b91af">NotNull</SPAN>]<SPAN style="COLOR: #2b91af">MutableString</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> path, [<SPAN style="COLOR: #2b91af">NotNull</SPAN>]<SPAN style="COLOR: #2b91af">MutableString</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> filter)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: #2b91af">MutableString</SPAN><SPAN style="FONT-SIZE: 10pt"> filename = Basename(context, self, path);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: green">//Treat ? specially</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">if</SPAN><SPAN style="FONT-SIZE: 10pt"> (filter.IndexOf(<SPAN style="COLOR: #a31515">'?'</SPAN>) &gt;= 0)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">return</SPAN><SPAN style="FONT-SIZE: 10pt"> filename;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: green">//Treat .* and exetions specially using regex</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">if</SPAN><SPAN style="FONT-SIZE: 10pt"> (filter.Equals(<SPAN style="COLOR: #2b91af">MutableString</SPAN>.Create(<SPAN style="COLOR: #a31515">".*"</SPAN>)))</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">filter.Clear();</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">filter.Append(<SPAN style="COLOR: #a31515">@"(?x)(\.[^.]*$|$)"</SPAN>);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">else</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">filter.Append(<SPAN style="COLOR: #a31515">"$"</SPAN>);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: #2b91af">RubyRegex</SPAN><SPAN style="FONT-SIZE: 10pt"> reg = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">RubyRegex</SPAN>(filter, System.Text.RegularExpressions.<SPAN style="COLOR: #2b91af">RegexOptions</SPAN>.Singleline);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">System.Text.RegularExpressions.<SPAN style="COLOR: #2b91af">Match</SPAN> mat = reg.Match(filename);</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">if</SPAN><SPAN style="FONT-SIZE: 10pt"> (mat.Success)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">filename.Replace(mat.Index, mat.Length, <SPAN style="COLOR: #2b91af">MutableString</SPAN>.Create(<SPAN style="COLOR: #a31515">""</SPAN>));</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">return</SPAN><SPAN style="FONT-SIZE: 10pt"> filename;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">[<SPAN style="COLOR: #2b91af">RubyMethod</SPAN>(<SPAN style="COLOR: #a31515">"basename"</SPAN>, <SPAN style="COLOR: #2b91af">RubyMethodAttributes</SPAN>.PublicSingleton)]</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">public</SPAN><SPAN style="FONT-SIZE: 10pt"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: #2b91af">MutableString</SPAN> Basename(<SPAN style="COLOR: #2b91af">CodeContext</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> context, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> self, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> path, <SPAN style="COLOR: blue">object</SPAN><SPAN style="COLOR: green">/*!*/</SPAN> filter)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">{</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; COLOR: blue">return</SPAN><SPAN style="FONT-SIZE: 10pt"> Basename(context, self, <SPAN style="COLOR: #2b91af">Protocols</SPAN>.CastToString(context, path), <SPAN style="COLOR: #2b91af">Protocols</SPAN>.CastToString(context, filter));</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">}</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">&nbsp;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">Let me know what do you think? Yes, I found some problems with test spec as well, (bar.txt should be baz)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">&nbsp;</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">Thanks.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt">&nbsp;</SPAN></P>
<DIV>
<P class=MsoNormal style="MARGIN-BOTTOM: 12pt">&nbsp;</P>
<DIV>
<P class=MsoNormal>----- Original Message ----<BR>From: John Lam (IRONRUBY) &lt;jflam@microsoft.com&gt;<BR>To: "ironruby-core@rubyforge.org" &lt;ironruby-core@rubyforge.org&gt;<BR>Sent: Saturday, May 10, 2008 3:25:16 PM<BR>Subject: Re: [Ironruby-core] RubyForge bug fixes<BR><BR>Unnikrishnan Nair:<BR><BR>&gt; Quick question, are these following assertions are correct?<BR>&gt;<BR>&gt;&nbsp; &nbsp; should_raise(TypeError){ File.basename(1) }<BR>&gt;&nbsp; &nbsp; should_raise(TypeError){ File.basename("bar.txt", 1) }<BR>&gt;&nbsp; &nbsp; should_raise(TypeError){ File.basename(true) }<BR><BR>Yes they are. You can easily verify this in MRI yourself.<BR><BR>In first and third cases, it hits the overload that accepts a nullable object as the first parameter. The TypeError is raised via Protocols.CastToString().<BR><BR>In the second case, it also hits an overload that accepts a nullable object as its second parameter, which raises TypeError via
 Protocols.CastToString().<BR><BR>FYI, this is the implementation of #basename that I have in my shelveset. It passes all of the (valid) specs - there are some legitimate bugs in our old copy of the specs (I haven't checked with the latest version of the rubinius specs - I'll do that next week). I'm a bit worried about how I'm handling the special cases for Windows.<BR><BR>[RubyMethod("basename", RubyMethodAttributes.PublicSingleton)]<BR>public static MutableString/*!*/ Basename(CodeContext/*!*/ context, object/*!*/ self, [NotNull]MutableString/*!*/ path, [NotNull]MutableString/*!*/ extensionFilter) {<BR>&nbsp; &nbsp; if (path.Length == 0)<BR>&nbsp; &nbsp; &nbsp; &nbsp; return path;<BR><BR>&nbsp; &nbsp; MutableString trimmedPath = TrimTrailingSlashes(path);<BR><BR>&nbsp; &nbsp; // Special cases of drive letters C:\\ or C:/<BR>&nbsp; &nbsp; if (trimmedPath.Length == 2)<BR>&nbsp; &nbsp; &nbsp; &nbsp; if (Char.IsLetter(trimmedPath.GetChar(0)) &amp;&amp;
 trimmedPath.GetChar(1) == ':')<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Kernel.FlowTaint(context, path, (path.Length &gt; 2 ? MutableString.Create(path.GetChar(2).ToString()) : MutableString.Create(String.Empty)));<BR><BR>&nbsp; &nbsp; string trimmedPathAsString = trimmedPath.ConvertToString();<BR>&nbsp; &nbsp; if (trimmedPathAsString == "/")<BR>&nbsp; &nbsp; &nbsp; &nbsp; return trimmedPath;<BR><BR>&nbsp; &nbsp; string filename = <A href="http://system.io.path.ge/" target=_blank rel=nofollow>System.IO</A>.Path.GetFileName(trimmedPath.ConvertToString());<BR><BR>&nbsp; &nbsp; // Handle UNC host names correctly<BR>&nbsp; &nbsp; string root = <A href="http://system.io.path.ge/" target=_blank rel=nofollow>System.IO</A>.Path.GetPathRoot(trimmedPath.ConvertToString());<BR>&nbsp; &nbsp; if (extensionFilter.Length == 0)<BR>&nbsp; &nbsp; &nbsp; &nbsp; return trimmedPathAsString == root ? MutableString.Create(root) :
 MutableString.Create(filename);<BR><BR>&nbsp; &nbsp; string fileExtension = <A href="http://system.io.path.ge/" target=_blank rel=nofollow>System.IO</A>.Path.GetExtension(filename);<BR>&nbsp; &nbsp; string basename = <A href="http://system.io.path.ge/" target=_blank rel=nofollow>System.IO</A>.Path.GetFileNameWithoutExtension(filename);<BR><BR>&nbsp; &nbsp; string result = WildcardExtensionMatch(fileExtension, extensionFilter.ConvertToString()) ? basename : filename;<BR>&nbsp; &nbsp; return Kernel.FlowTaint(context, self, (result.Equals(root) ? MutableString.Create(root) : MutableString.Create(result)));<BR>}<BR><BR>[RubyMethod("basename", RubyMethodAttributes.PublicSingleton)]<BR>public static MutableString/*!*/ Basename(CodeContext/*!*/ context, object/*!*/ self, [NotNull]MutableString/*!*/ path) {<BR>&nbsp; &nbsp; return Basename(context, self, path, MutableString.Empty);<BR>}<BR><BR>[RubyMethod("basename",
 RubyMethodAttributes.PublicSingleton)]<BR>public static MutableString/*!*/ Basename(CodeContext/*!*/ context, object/*!*/ self, object path, object extension) {<BR>&nbsp; &nbsp; return Basename(context, self, Protocols.CastToString(context, path), Protocols.CastToString(context, extension));<BR>}<BR><BR>[RubyMethod("basename", RubyMethodAttributes.PublicSingleton)]<BR>public static MutableString/*!*/ Basename(CodeContext/*!*/ context, object/*!*/ self, object path) {<BR>&nbsp; &nbsp; return Basename(context, self, Protocols.CastToString(context, path));<BR>}<BR><BR>&gt; Also, in the basename_spec the test setup has wrong parameter on<BR>&gt; File.open(@name, 'w+'), if I change it to 'w', the test runs fine<BR>&gt; otherwise none of the test works.<BR><BR>This is correct. There is a bug in how we map the semantics of 'w+' to .NET IO. It's fixed in my
 shelveset.<BR><BR>Thanks,<BR>-John<BR><BR><BR><BR>_______________________________________________<BR>Ironruby-core mailing list<BR><A href="mailto:Ironruby-core@rubyforge.org" target=_blank rel=nofollow ymailto="mailto:Ironruby-core@rubyforge.org">Ironruby-core@rubyforge.org</A><BR><A href="http://rubyforge.org/mailman/listinfo/ironruby-core" target=_blank rel=nofollow>http://rubyforge.org/mailman/listinfo/ironruby-core</A></P></DIV></DIV></DIV></DIV></DIV></div></body></html>