# Digest.so implemented

**URL:** <https://www.ruby-forum.com/t/digest-so-implemented/130427>\
**Category:** IronRuby\
**Created:** [February 28, 2008, 4:59am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427 "2008-02-28T04:59:09Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 28, 2008, 4:59am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/1 "2008-02-28T04:59:09Z")

</div>

Attached is an implementation of the methods and classes from external  
library digest.so that are used by some simple Rails use cases.

* * *

I note, that the IronRuby pattern for supporting custom object cloning  
it to implement the IDuplicable interface. Is there some reason for this  
approach rather than using Ruby’s standard mechanism of implementing an  
initialize\_copy method? With the latter approach, Ruby programmers can  
implement their own copy semantics, eg:

class Foo  
def initialize\_copy©  
puts ‘copying’  
end  
end  
f = Foo.new  
g = f.clone

Cheers, Wayne.

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 28, 2008, 9:00am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/2 "2008-02-28T09:00:48Z")

</div>

2008/2/28, Wayne K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Attached is an implementation of the methods and classes from external library digest.so that are used by some simple Rails use cases.

This implementation appends all strings hashed to the buffer. Which  
means, if you hash 100 MB file, each megabyte incrementally, 100 MB  
MutableString is allocated. This is unnecessary, and can be avoided by  
using TransformBlock.

FePy’s implementation of hashlib extension module uses this method. See:

> **[FePy](https://sourceforge.net/projects/fepy/)**
>
> Download FePy for free. FePy project aims to provide enhancements and add-ons for IronPython, an implementation of Python programming language.

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 28, 2008, 9:42am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/3 "2008-02-28T09:42:38Z")

</div>

You are really on a roll Wayne. Great stuff!

I might be wrong but my impression of the IronRuby support for the  
various  
.NET interfaces, such as IDuplicable, IEnumerable and so on, was purely  
to  
support .NET interop and not designed to be the mechanism used by actual  
Ruby libraries. So I suppose the most comprehensive method would be to  
support both initialize\_copy and IDuplicable if you can and then one or  
the  
other if you can’t (i.e. you are developing only in Ruby or you have a  
3rd  
party .NET class).

Correct me if I’m wrong.

Pete

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 29, 2008, 12:57am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/4 "2008-02-29T00:57:46Z")

</div>

> incrementally, 100 MB MutableString is allocated. This is  
> unnecessary, and can be avoided by using TransformBlock.

Hi Seo,

Thanks for raising this. I was aware of the performance issue and my  
original implementation did use the TransformBlock method, but I  
switched to an explicit buffer approach in order to support cloning of  
digest objects. I didn’t think/realize it was possible to clone .NET  
Crypto objects.

I see you use the MemberwiseClone method. Firstly, I thought this was a  
protected member, how are you able to directly call it on your context  
objects? Secondly, is the shallow copy that MemberwiseClone performs  
going to give us the correct cloning semantics?

P.S. I notice your module is implemented in Python - I hadn’t even  
contemplated the idea of implementing these libraries in Ruby - I guess  
because I’m a C# developer. Do people think we should rewrite these  
extension libraries in Ruby?

Cheers, Wayne.

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 29, 2008, 5:42am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/5 "2008-02-29T05:42:43Z")

</div>

2008/2/29, Wayne K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Thanks for raising this. I was aware of the performance issue and my original implementation did use the TransformBlock method, but I switched to an explicit buffer approach in order to support cloning of digest objects. I didn’t think/realize it was possible to clone .NET Crypto objects.
> 
> I see you use the MemberwiseClone method. Firstly, I thought this was a protected member, how are you able to directly call it on your context objects? Secondly, is the shallow copy that MemberwiseClone performs going to give us the correct cloning semantics?

I think visibility is enforced by compiler, not runtime. For example,  
one can access private members by reflection or by bytecode  
generation. In general, IronPython can access protected members by  
default, and private members when explicitly asked.

Hash implementations are fully managed (in .NET and Mono), and shallow  
copying by MemberwiseClone does give the correct semantics _now_.  
hashlib.py is currently in production use. However, I don’t think that  
MemberwiseClone gives correct semantics is guaranteed by explicit  
documentation.

> P.S. I notice your module is implemented in Python - I hadn’t even contemplated the idea of implementing these libraries in Ruby - I guess because I’m a C# developer. Do people think we should rewrite these extension libraries in Ruby?

Writing in Ruby does simplify some boilerplates code, doesn’t it?

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 29, 2008, 2:18pm UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/6 "2008-02-29T14:18:49Z")

</div>

I thought that the general idea in Ruby circles was that all their  
libraries  
should be written in Ruby unless there was some important reason not to,  
such as performance or access to underlying OS or hardware functionality  
that was not available to Ruby code?

The Rubinius guys took this one step further and have pretty much  
implemented everything in Ruby (including the runtime engine itself) and  
where they needed to access the OS directly they have created hooks into  
the  
operating system via “special” Rubinius operations that allow the ruby  
code  
to do the stuff.

Interestingly, they then run into the problem of people monkey patching  
their runtime engine by accident, which is what happened when you  
required  
the math library which changed the way division works in integers and  
this  
broke their implementation of indexing arrays.

If the DLR is going to compile up the Ruby code into IL anyway then it  
should not be a huge performance problem to write most libraries in Ruby  
and  
then use IR .NET interop to access any underlying functionality that is  
not  
normally available in Ruby.

\*\*\*\* This would also have the benefit of removing the excuse of non-C#  
developers from contributing to the IR libraries!! \*\*\*\*

Pete

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [March 2, 2008, 6:24am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/7 "2008-03-02T06:24:08Z")

</div>

Peter Bacon D. wrote:

> If the DLR is going to compile up the Ruby code into IL anyway then it  
> should not be a huge performance problem to write most libraries in Ruby and  
> then use IR .NET interop to access any underlying functionality that is not  
> normally available in Ruby.
> 
> \*\*\*\* This would also have the benefit of removing the excuse of non-C#  
> developers from contributing to the IR libraries!! \*\*\*\*

One of the other problems the Rubinius guys face is performance. In  
other words, they’re very slow for normal apps because in order for an  
all-Ruby set of core classes to perform well, the underlying enging  
needs to be _much_ faster than a normal Ruby implementation.

I don’t doubt that IronRuby will be able to achieve really good  
performance, as IronPython has done…but I would be very surprised if  
it were able to achieve performance high enough to offset the cost of  
implementing core classes in Ruby. That said, implementing them in Ruby  
first saves you some implementation hassle, and helps the Ruby community  
in general by providing implementations that most current and new Ruby  
impls should be able to run. But I wouldn’t bank on using those Ruby  
versions long term, unless you can afford to swallow the almost-certain  
performance hit.

- Charlie

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [March 2, 2008, 7:22am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/8 "2008-03-02T07:22:08Z")

</div>

2008/3/2, Charles Oliver N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I don’t doubt that IronRuby will be able to achieve really good  
> performance, as IronPython has done…but I would be very surprised if  
> it were able to achieve performance high enough to offset the cost of  
> implementing core classes in Ruby. That said, implementing them in Ruby  
> first saves you some implementation hassle, and helps the Ruby community  
> in general by providing implementations that most current and new Ruby  
> impls should be able to run. But I wouldn’t bank on using those Ruby  
> versions long term, unless you can afford to swallow the almost-certain  
> performance hit.

Well, in case of digest.so, I’m not suggesting implementing MD5  
algorithm in Ruby (which would be slooow), but implementing the  
wrapper around .NET classes in System.Security.Cryptography in Ruby  
instead of C#. Performance impact would be negligible.

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [February 29, 2008, 2:44pm UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/9 "2008-02-29T14:44:55Z")

</div>

Implementing as much as possible in Ruby sounds like a plan, because as  
you  
say it means us Rubyist can avoid C#. As you say, there shouldn’t be any  
performance hit as it all gets compiled to IL.

Obviously we need some base parts of the language complete first though  
🙂

* * *

Myles E.  
Mobile: +61-409-293-183

MadPilot Productions  
URL: [http://www.madpilot.com.au](http://www.madpilot.com.au)  
Phone: +618-9467-7651  
Fax: +618-9467-6289

Try our time tracking system: 88 Miles!

> **[88miles.net - This website is for sale! - 88miles...](https://www.88miles.net)**
>
> This website is for sale! 88miles.net is your first and best source for all of the information you’re looking for. From general topics to more of what you would expect to find here, 88miles.net has it all. We hope you find what you are searching for!

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [March 3, 2008, 3:26pm UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/10 "2008-03-03T15:26:45Z")

</div>

Sanghyeon S.:

> Well, in case of digest.so, I’m not suggesting implementing MD5  
> algorithm in Ruby (which would be slooow), but implementing the wrapper  
> around .NET classes in System.Security.Cryptography in Ruby instead of  
> C#. Performance impact would be negligible.

+1 on this. This is the right approach.

Thanks,  
-John

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [April 14, 2011, 9:45pm UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/11 "2011-04-14T21:45:10Z")

</div>

RubyMne [http://www.jetbrains.com/ruby/](http://www.jetbrains.com/ruby/) works pretty well.

-Charles

---

<div class="post-metadata">

**Author:** ![Wayne\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/b5ac83/32.png) [@Wayne\_K](https://www.ruby-forum.com/u/Wayne_K)\
**Post date:** [April 13, 2011, 3:29am UTC](https://www.ruby-forum.com/t/digest-so-implemented/130427/12 "2011-04-13T03:29:53Z")

</div>

This is very much an ARGH!!!

Time line: Friday get confirmation about an interview using Ruby.  
Google for IDE and find Ruby in Steel. Yea (ruby 1.86 in the free  
version).

Read the “Book of Ruby” and start my first Ruby application.  
For my first application I choose Solve KenKen puzzles.

At some point I need to make a deep copy. I define my initialize\_copy  
method. The assumption is this will actually be ran, but NO!

I have not looked into implementing the IDuplicable interface. This is  
what I ended up doing.

if equation.validEquation  
newEquation = equation.clone  
newEquation.initialize\_copy(newEquation) #should not have to do  
this. very anoying  
@equations \<\< newEquation # need to make this a deep copy.  
end

ARGH!!! ARGH!!!

Is there a free ide that does plain Ruby vs. IronRuby?
