# Injecting dynamic methods into a class

**URL:** <https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980>\
**Category:** ruby-talk\
**Created:** [4 December 2005 04:11 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980 "2005-12-04T04:11:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [4 December 2005 04:11 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/1 "2005-12-04T04:11:11Z")

</div>

hi All,

I posted this message to the Ruby on Rails group yesterday, but I  
suppose it belongs here instead.

I've been trying to wrestle dynamic code generation into place for a  
week now with no success. What I want is a module or class (started  
trying to use module but finished up trying to use a class) which can  
inject a method into its consumer which will allow:

user.image = #\<Ruby:File\>

as you would get from a file upload. (This eliminates any need for  
special image handling code in the view or controller and lets the image  
field act like any other). It uses the RMagick library to convert all  
images to jpg's and resize them to a consumer-defined size. What I was  
hoping the group could help with was moving all the code out of the  
model and into my ImageBlob class (which will inject necessary code into  
the model (i.e., consumer)). Here's what I currently have (which  
works):

model.rb

> **···**
>
> ----------  
> def image=( file )  
> &nbsp;&nbsp;write\_attribute( 'image', ImageBlob.getBlob( file, 225 ))  
> end  
> def thumbnailImage=( file )  
> &nbsp;&nbsp;write\_attribute( 'thumbnailImage', ImageBlob.getBlob( file, 125  
> ))  
> end
> 
> ImageBlob.rb  
> ------------  
> require 'RMagick'  
> include Magick
> 
> class ImageBlob  
> &nbsp;&nbsp;def ImageBlob.getBlob( file, maxImageSize )  
> &nbsp;&nbsp;&nbsp;&nbsp;#omitted code which resizes and reformats image and returns blob  
> &nbsp;&nbsp;end  
> end
> 
> I was hoping to have an initialize function in ImageBlob which would  
> take the consumer class and inject the necessary methods into it (image=  
> and thumbnailImage=). Here's my best attempt at that (which fails for  
> an unknown reason):
> 
> def initialize( attributesAndSizesHash, consumerClass )  
> &nbsp;&nbsp;attributesAndSizesHash.each\_pair {|attributeName, maxImageSize|  
> &nbsp;&nbsp;&nbsp;&nbsp;code = "class #{consumerClass}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attributeName}=( file )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attributeName}', ImageBlob.getBlob(  
> file, #{maxImageSize} ))  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end"  
> &nbsp;&nbsp;&nbsp;&nbsp;eval( code ) }  
> end
> 
> I also tried making 'code' define a module and calling  
> consumerClass.extend( moduleName ). Neither of these approaches are  
> working.
> 
> Of course, if this implemention could work, then consumers of the  
> ImageBlob class could simply call:
> 
> ImageBlob.new( { "image" =\> 225, "thumbnailImage" =\> 125 }, self )
> 
> in their class definition to have the functionality added (with  
> any number of image fields each having their own size).
> 
> Can anyone out there provide the last piece of this puzzle?
> 
> Thanks much,  
> Jonathan
> 
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [4 December 2005 04:34 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/2 "2005-12-04T04:34:54Z")

</div>

Hi --

> hi All,
> 
> I posted this message to the Ruby on Rails group yesterday, but I  
> suppose it belongs here instead.
> 
> I've been trying to wrestle dynamic code generation into place for a  
> week now with no success. What I want is a module or class (started  
> trying to use module but finished up trying to use a class) which can  
> inject a method into its consumer which will allow:
> 
> user.image = #\<Ruby:File\>
> 
> as you would get from a file upload. (This eliminates any need for  
> special image handling code in the view or controller and lets the image  
> field act like any other). It uses the RMagick library to convert all  
> images to jpg's and resize them to a consumer-defined size. What I was  
> hoping the group could help with was moving all the code out of the  
> model and into my ImageBlob class (which will inject necessary code into  
> the model (i.e., consumer)). Here's what I currently have (which  
> works):
> 
> model.rb  
> ----------  
> def image=( file )  
> &nbsp;&nbsp;write\_attribute( 'image', ImageBlob.getBlob( file, 225 ))  
> end  
> def thumbnailImage=( file )  
> &nbsp;&nbsp;write\_attribute( 'thumbnailImage', ImageBlob.getBlob( file, 125  
> ))  
> end
> 
> ImageBlob.rb  
> ------------  
> require 'RMagick'  
> include Magick
> 
> class ImageBlob  
> &nbsp;&nbsp;def ImageBlob.getBlob( file, maxImageSize )  
> &nbsp;&nbsp;&nbsp;&nbsp;#omitted code which resizes and reformats image and returns blob  
> &nbsp;&nbsp;end  
> end
> 
> I was hoping to have an initialize function in ImageBlob which would  
> take the consumer class and inject the necessary methods into it (image=  
> and thumbnailImage=). Here's my best attempt at that (which fails for  
> an unknown reason):
> 
> def initialize( attributesAndSizesHash, consumerClass )  
> &nbsp;&nbsp;attributesAndSizesHash.each\_pair {|attributeName, maxImageSize|  
> &nbsp;&nbsp;&nbsp;&nbsp;code = "class #{consumerClass}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attributeName}=( file )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attributeName}', ImageBlob.getBlob(  
> file, #{maxImageSize} ))  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end"  
> &nbsp;&nbsp;&nbsp;&nbsp;eval( code ) }  
> end
> 
> I also tried making 'code' define a module and calling  
> consumerClass.extend( moduleName ). Neither of these approaches are  
> working.
> 
> Of course, if this implemention could work, then consumers of the  
> ImageBlob class could simply call:
> 
> ImageBlob.new( { "image" =\> 225, "thumbnailImage" =\> 125 }, self )
> 
> in their class definition to have the functionality added (with  
> any number of image fields each having their own size).
> 
> Can anyone out there provide the last piece of this puzzle?

I don't know if this is an exact fit, but I've tried to model it on what  
your example. The basic idea here is to call class\_eval on the class  
that's passed in, and proceed from there (defining the methods).

&nbsp;&nbsp;class ImageBlob  
&nbsp;&nbsp;&nbsp;&nbsp;def self.get\_blob(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "In ImageBlob.get\_blob"  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;class MyClass  
&nbsp;&nbsp;&nbsp;&nbsp;def initialize(attrs\_and\_sizes, klass)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attrs\_and\_sizes.each\_pair do |attr\_name,max\_image\_size|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.class\_eval do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;define\_method("#{attr\_name}=") do |file|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute(attr\_name,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ImageBlob.get\_blob(file,max\_image\_size))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;class OtherClass  
&nbsp;&nbsp;&nbsp;&nbsp;def write\_attribute(\*args)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "In write\_attribute"  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;m = MyClass.new({"a" =\> 10, "b" =\> 20}, OtherClass)  
&nbsp;&nbsp;OtherClass.new.a = 2

(If you're passing in a classname string, rather than a class, you'd also  
want to do some variant of const\_get to get the class itself before  
class\_eval'ing from it.)

David Black

> **···**
>
> On Sun, 4 Dec 2005, johanatan wrote:

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [4 December 2005 04:42 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/3 "2005-12-04T04:42:33Z")

</div>

If you don't mind while I'm at this I'm going to touch up the code to  
follow ruby conventions.

&nbsp;&nbsp;def initialize( attr\_and\_sizes\_hash, consumer\_class )  
&nbsp;&nbsp;&nbsp;&nbsp;attr\_and\_sizes\_hash.each {|attr\_name, max\_size|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = %{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attr\_name}=( file )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attr\_name}', ImageBlob.getBlob( file,  
#{max\_size} ) )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consumer\_class.class\_eval code  
&nbsp;&nbsp;end

BTW it seems odd to use the #initialize method of ImageBob to do this.

HTH,  
T.

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [5 December 2005 01:44 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/4 "2005-12-05T01:44:27Z")

</div>

transfire wrote:

> If you don't mind while I'm at this I'm going to touch up the code to  
> follow ruby conventions.

I don't mind at all. I'm new to ruby so I haven't picked up on the  
extensions yet. 🙂

> &nbsp;&nbsp;def initialize( attr\_and\_sizes\_hash, consumer\_class )  
> &nbsp;&nbsp;&nbsp;&nbsp;attr\_and\_sizes\_hash.each {|attr\_name, max\_size|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = %{  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attr\_name}=( file )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attr\_name}', ImageBlob.getBlob( file,  
> #{max\_size} ) )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consumer\_class.class\_eval code  
> &nbsp;&nbsp;end

I didn't try class\_eval. Did you test this or is it just a theory? 🙂  
Seemed like regular eval and extend should work.

> BTW it seems odd to use the #initialize method of ImageBob to do this.

It is odd, but the ImageBlob class contains only one class method (i.e.,  
static method) and no data members, so no actual memory should be  
defined for it. I suppose it could have contained two class methods  
instead of using initialize (that is better so I'll change that). At  
first, I was trying to store a ptr to the ImageBlob instance in the  
consumer class but realized it wasn't necessary.

Much thanks for the answers.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [5 December 2005 01:53 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/5 "2005-12-05T01:53:35Z")

</div>

Ok. The class is ready for consumption. 🙂 Here it is:

require 'RMagick'  
include Magick

class ImageBlob

&nbsp;&nbsp;def ImageBlob.inject\_attrib\_assign\_methods( attr\_and\_sizes\_hash,  
consumer\_class )  
&nbsp;&nbsp;&nbsp;&nbsp;attr\_and\_sizes\_hash.each {|attr\_name, max\_size|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = %{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attr\_name}=( file )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attr\_name}', ImageBlob.getBlob( file,  
#{max\_size} ))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consumer\_class.class\_eval code }  
&nbsp;&nbsp;end

&nbsp;&nbsp;def ImageBlob.getBlob( file, max\_image\_size )  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if not img  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img.format = "JPG"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if img.rows \> max\_image\_size or img.columns \> max\_image\_size  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if img.rows \> img.columns  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factor = max\_image\_size / img.rows.to\_f  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factor = max\_image\_size / img.columns.to\_f  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = img.scale( factor )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retVal = img.to\_blob  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GC.start  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return retVal  
&nbsp;&nbsp;&nbsp;&nbsp;rescue  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return nil  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [5 December 2005 02:22 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/6 "2005-12-05T02:22:33Z")

</div>

> transfire wrote:  
> \> If you don't mind while I'm at this I'm going to touch up the code to  
> \> follow ruby conventions.
> 
> I don't mind at all. I'm new to ruby so I haven't picked up on the  
> extensions yet. 🙂

Understandable. As you've noticed Matz prefers underscores and  
lowercase over camelcase for methd names, so that's become the general  
convention. There's alos a tendency to get them as small as possible  
while still being human readable/self-documenting.

> \>  
> \> def initialize( attr\_and\_sizes\_hash, consumer\_class )  
> \> attr\_and\_sizes\_hash.each {|attr\_name, max\_size|  
> \> code = %{  
> \> def #{attr\_name}=( file )  
> \> write\_attribute( '#{attr\_name}', ImageBlob.getBlob( file,  
> \> #{max\_size} ) )  
> \> end  
> \> }  
> \> consumer\_class.class\_eval code  
> \> end  
> \>
> 
> I didn't try class\_eval. Did you test this or is it just a theory? 🙂  
> Seemed like regular eval and extend should work.

I didn't test, but I've used it enough times to know that the way to go  
about it (even I made a booboo in my code) You'll notice David used it  
in his variation too.

> \> BTW it seems odd to use the #initialize method of ImageBob to do this.
> 
> It is odd, but the ImageBlob class contains only one class method (i.e.,  
> static method) and no data members, so no actual memory should be  
> defined for it. I suppose it could have contained two class methods  
> instead of using initialize (that is better so I'll change that). At  
> first, I was trying to store a ptr to the ImageBlob instance in the  
> consumer class but realized it wasn't necessary.

If ImagaBob is not instantiable then a module would be better than a  
class.

> Much thanks for the answers.

No problemo.

T.

> **···**
>
> johanatan \<zjll9@imail.etsu.edu\> \<zjll9@imail.etsu.edu\> wrote:

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [5 December 2005 01:55 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/7 "2005-12-05T01:55:04Z")

</div>

An example of using this is:

in a class definition:

> **···**
>
> ----------------------  
> ImageBlob.inject\_attrib\_assign\_methods( { "image" =\> 225,  
> "thumbnailImage" =\> 125 }, self )
> 
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [5 December 2005 02:37 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/8 "2005-12-05T02:37:35Z")

</div>

Couple suggestions:

&nbsp;&nbsp;def ImageBlob.inject\_attrib\_assign\_methods

to

&nbsp;&nbsp;def self.inject\_accessors

Using 'self' is more robust. Also in Ruby attribute methods are  
generally refered to as accessors.

&nbsp;&nbsp;def ImageBlob.getBlob( file, max\_image\_size )  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if not img  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

to

&nbsp;&nbsp;def self.get\_blob( file, max\_image\_size )  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return nil if not img

Don't use camelcase (unless you're passionate about it) and there's no  
need to raise if the rescue clause is just going ot return nil anyway.

T.

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [6 December 2005 01:53 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/9 "2005-12-06T01:53:03Z")

</div>

transfire wrote:

> Couple suggestions:
> 
> &nbsp;&nbsp;def ImageBlob.inject\_attrib\_assign\_methods
> 
> to
> 
> &nbsp;&nbsp;def self.inject\_accessors
> 
> Using 'self' is more robust. Also in Ruby attribute methods are  
> generally refered to as accessors.

I agree with the name change. However, the class isn't instantiable, so  
using self won't work. I will change this to a module though. (you can  
call methods of a module without mixing it in right?)

> &nbsp;&nbsp;def ImageBlob.getBlob( file, max\_image\_size )  
> &nbsp;&nbsp;&nbsp;&nbsp;begin  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if not img  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> to
> 
> &nbsp;&nbsp;def self.get\_blob( file, max\_image\_size )  
> &nbsp;&nbsp;&nbsp;&nbsp;begin  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return nil if not img
> 
> Don't use camelcase (unless you're passionate about it) and there's no  
> need to raise if the rescue clause is just going ot return nil anyway.

Thanks for point that out. I overlooked getBlob.

--Jonathan

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [6 December 2005 02:05 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/10 "2005-12-06T02:05:38Z")

</div>

transfire wrote:

> Using 'self' is more robust. Also in Ruby attribute methods are  
> generally refered to as accessors.

I've always heard 'accessor' refers to a get\_prop method and 'assigner'  
refers to a set\_prop method. Does accessor refer to both in Ruby?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [6 December 2005 01:56 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/11 "2005-12-06T01:56:33Z")

</div>

Here's the updated code:

require 'RMagick'  
include Magick

module ImageBlob

&nbsp;&nbsp;def ImageBlob.inject\_assigners( attr\_and\_sizes\_hash,  
consumer\_class )  
&nbsp;&nbsp;&nbsp;&nbsp;attr\_and\_sizes\_hash.each {|attr\_name, max\_size|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;code = %{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def #{attr\_name}=( file )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write\_attribute( '#{attr\_name}', ImageBlob.get\_blob( file,  
#{max\_size} ))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consumer\_class.class\_eval code }  
&nbsp;&nbsp;end

&nbsp;&nbsp;def ImageBlob.get\_blob( file, max\_image\_size )  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = Image.from\_blob( file.read ).first  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return nil if not img

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img.format = "JPG"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if img.rows \> max\_image\_size or img.columns \> max\_image\_size  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if img.rows \> img.columns  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factor = max\_image\_size / img.rows.to\_f  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factor = max\_image\_size / img.columns.to\_f  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;img = img.scale( factor )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret\_val = img.to\_blob  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GC.start  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret\_val  
&nbsp;&nbsp;&nbsp;&nbsp;rescue  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return nil  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [6 December 2005 02:01 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/12 "2005-12-06T02:01:10Z")

</div>

> I agree with the name change. However, the class isn't instantiable, so  
> using self won't work. I will change this to a module though. (you can  
> call methods of a module without mixing it in right?)

Oops. I guess 'self' in that context refers to the module or class??  
Yea, that would be more robust (or at least more consistent with  
write-once. changing the name of a class or module would require  
changing all static method names (are these called class methods in  
ruby??) unless self is used. Is that the reason you think it's more  
robust or was it something else?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [6 December 2005 02:12 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/13 "2005-12-06T02:12:37Z")

</div>

> However, the class isn't instantiable, so using self won't work.

Sure it will. 'self' just refers to the current context, in either case  
whether class or module that's what it is. So it should work fine.

> (you can call methods of a module without mixing it in right?)

Yes, if they are "module methods" as opposed to instance methods.  
Modules methods, (also called class methods but usually in the context  
of class) are singleton methods, or adhoc methods (my new prefered  
term). You can tell this by the way they are defined --the name of the  
object proceeds the method name in the def statement (eg. 'def  
ImageBob.get\_blob'). Another way to write them:

&nbsp;&nbsp;module ImageBlob

&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self # opens adhoc context

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def get\_blob  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;end

T.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [6 December 2005 02:17 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/14 "2005-12-06T02:17:34Z")

</div>

> I've always heard 'accessor' refers to a get\_prop method and 'assigner'  
> refers to a set\_prop method. Does accessor refer to both in Ruby?

Yes, becuase of the common convenience method:

&nbsp;&nbsp;attr\_accessor :a

which creates both a "reader" and a "writer", which are the terms Ruby  
generally uses. What I mean by \*convenience\* method is that the above  
is simply a shortcut for doing:

&nbsp;&nbsp;def a  
&nbsp;&nbsp;&nbsp;&nbsp;@a  
&nbsp;&nbsp;end

&nbsp;&nbsp;def a=(x)  
&nbsp;&nbsp;&nbsp;&nbsp;@a = x  
&nbsp;&nbsp;end

And is the same as doing

&nbsp;&nbsp;attr\_reader :a  
&nbsp;&nbsp;attr\_writer :a

T.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [6 December 2005 02:22 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/15 "2005-12-06T02:22:33Z")

</div>

Nope, that's it exactly.

T.

> **···**
>
> Jonathan \<zjll9@imail.etsu.edu\> \<zjll9@imail.etsu. wrote:
> 
> > \>  
> > \> I agree with the name change. However, the class isn't instantiable, so  
> > \> using self won't work. I will change this to a module though. (you can  
> > \> call methods of a module without mixing it in right?)
> > 
> > Oops. I guess 'self' in that context refers to the module or class??  
> > Yea, that would be more robust (or at least more consistent with  
> > write-once. changing the name of a class or module would require  
> > changing all static method names (are these called class methods in  
> > ruby??) unless self is used. Is that the reason you think it's more  
> > robust or was it something else?

---

<div class="post-metadata">

**Author:** ![Ross\_Bamford2](https://avatars.discourse-cdn.com/v4/letter/r/e47774/32.png) [@Ross\_Bamford2](https://rubytalk.org/u/Ross_Bamford2)\
**Post date:** [6 December 2005 02:57 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/16 "2005-12-06T02:57:39Z")

</div>

I know I'm new, but humour me if you will ?

Firstly, what's wrong with 'singleton'? It seems to me that it fits well, and makes the usage obvious to the reader (well, me, but I assume others too?). Secondly, 'Ad-hoc' seems to be a really odd choice to me. I am aware that it can be taken to mean 'Specific to a given problem', but it is also defined along the lines of 'impromtu', 'temporary' or 'disorganized'. Science uses it to mean a quick fix for a flawed theory. Upon seeing the word ad-hoc I tend to imagine 'jury rigged' - stuck together with duct tape to last us out the storm.

Indeed, someone given to 'adhocism' (IMHO an awful word) exhibits 'the tendency to use temporary, provisional, or improvised methods to deal with a particular problem'. I wouldn't want my solutions to be seen as 'temporary' or 'provisional', whether tailor-made or otherwise.

I'm sure this is an ongoing debate, and I don't want to tread on any beliefs, but I just thought I'd offer a perspective from a fresh pair of eyes. Is there a serious movement to replace 'singleton'?

> **···**
>
> On Tue, 06 Dec 2005 02:10:51 -0000, Trans \<transfire@gmail.com\> wrote:
> 
> > > ... singleton methods, or adhoc methods (my new prefered
> > 
> > term).
> 
> --  
> Ross Bamford - rosco@roscopeco.remove.co.uk  
> "\e[1;31mL"

---

<div class="post-metadata">

**Author:** ![HAL\_9000](https://avatars.discourse-cdn.com/v4/letter/h/90ced4/32.png) [@HAL\_9000](https://rubytalk.org/u/HAL_9000)\
**Post date:** [6 December 2005 03:14 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/17 "2005-12-06T03:14:12Z")

</div>

Ross Bamford wrote:

> I know I'm new, but humour me if you will ?
> 
> Firstly, what's wrong with 'singleton'?

[snippage]

It doesn't really bother me. But there is some confusion with  
the Singleton pattern, and with other similar usages.

> I'm sure this is an ongoing debate, and I don't want to tread on any beliefs, but I just thought I'd offer a perspective from a fresh pair of eyes. Is there a serious movement to replace 'singleton'?

Some people want to change it, I think. If it must be changed, I  
would favor something like "singular class" (and I agree with your  
assessment of "ad hoc"). Some have suggested "eigenclass" -- and I  
admit this is a cool-sounding word, reminding me of my math and physics  
(and German) in college. But I can't really advocate it seriously.

Hal

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [6 December 2005 04:22 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/18 "2005-12-06T04:22:34Z")

</div>

Ross Bamford wrote:

> \>\> ... singleton methods, or adhoc methods (my new prefered  
> \> term).
> 
> I know I'm new, but humour me if you will ?
> 
> Firstly, what's wrong with 'singleton'? It seems to me that it fits well,  
> and makes the usage obvious to the reader (well, me, but I assume others  
> too?).

There has been much discussion about this. The problem with the term  
singleton is that it clashes with singleton design pattern, which is  
something different altogether. B/c of this much discussion has been  
given to finding a better term.

Now, The original term I believe was "virtual class", indeed you will  
still find an error or two in core that uses that phrase. I'm not sure  
you will find the term "singleton" anywhere in the source though. Also  
the the term "metaclass" was used when the context is of a class' or  
module's singleton class. But metaclass fell out of favor --I think  
b/c matz said he didn't like it. So "singleton" came along to sort of  
fill the void, not so much for its particular merits, but more for the  
lack of something better. Also I point out we have other terms that can  
cause confusion, although they too refer to the same thing just in a  
particular usage, namely "class methods" and "module methods".

About a year ago, I was having to decide what term to use in Facets, I  
included the ususal fair but wan't happy about having to have so many  
methods all for the same thing. So I tried to find a more suitable term  
that we all could generally agree on. I've tried out a few ideas, but  
none of them really worked. Around that time \_why the lucky stiff came  
up with the term "eigenclass", and that has had some sticking power, no  
doubt in part due to the ingenius humor he can bring to things. I think  
it a fairly good term, and I think we should keep using it and even get  
a bit more serious about it, tough obviously it still lacks in certain  
respects. I had all but given up on finding a better term until I  
accidently came acrosss "ad hoc". And I've actually been surprised and  
delighted at just how well that term works.

> Secondly, 'Ad-hoc' seems to be a really odd choice to me. I am  
> aware that it can be taken to mean 'Specific to a given problem', but it  
> is also defined along the lines of 'impromtu', 'temporary' or  
> 'disorganized'. Science uses it to mean a quick fix for a flawed theory.  
> Upon seeing the word ad-hoc I tend to imagine 'jury rigged' - stuck  
> together with duct tape to last us out the storm.

You see that's not the actual definition of the term. That's more of  
the vague understanding one gathers from not actually knowing the  
meaning. Although that vague idea has become widespread enough to be  
acknolwedged, it is still a secondary usage. I understand where you're  
coming from though, b/c I thought much the same way until I had used  
the word inproperly and my Grandmother corrected me. I wasn't so sure,  
so we looked it up in the dictionary and sure enough she was right. The  
definition is quite clear. From Websters (and others):

&nbsp;&nbsp;Main Entry: 1ad hoc  
&nbsp;&nbsp;Pronunciation: 'ad-'häk, -'hOk; 'äd-'hOk  
&nbsp;&nbsp;Function: adverb  
&nbsp;&nbsp;Etymology: Latin, for this  
&nbsp;&nbsp;: for the particular end or case at hand without consideration of  
wider application

That's how I realized the term would make a good fit.

> Indeed, someone given to 'adhocism' (IMHO an awful word)  
> exhibits 'the tendency to use temporary, provisional, or improvised methods to deal with  
> a particular problem'. I wouldn't want my solutions to be seen as  
> 'temporary' or 'provisional', whether tailor-made or otherwise.

Yep, "adhocism" is a bad term, it's fairly recent, hardly known, and  
really a misuse of the term adhoc. One gets this shade of meaning from  
applying the term to a particular \*moment\* --its the purpose itself  
that is temporary or provisional, not the "for" of it.

> I'm sure this is an ongoing debate, and I don't want to tread on any  
> beliefs, but I just thought I'd offer a perspective from a fresh pair of  
> eyes. Is there a serious movement to replace 'singleton'?

I did a survey once and people's opinions are all over the map. I  
personaly would like to see a solid term. I think 'adhoc' works well  
becuase it is small, ponient and has the added advantage (which none of  
the other choices have) of being an adverb, so it has very flexible  
usage. I guess my end preference to all this is that we migrate to the  
terms 'adhoc' and 'eigenclass' as is suitable. But I think this will  
happen naturally if the terms work.

T.

> **···**
>
> > On Tue, 06 Dec 2005 02:10:51 -0000, Trans \<transfire@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Jonathan\_zjll9](https://avatars.discourse-cdn.com/v4/letter/j/858c86/32.png) [@Jonathan\_zjll9](https://rubytalk.org/u/Jonathan_zjll9)\
**Post date:** [6 December 2005 04:03 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/19 "2005-12-06T04:03:16Z")

</div>

> It doesn't really bother me. But there is some confusion with  
> the Singleton pattern, and with other similar usages.
> 
> > I'm sure this is an ongoing debate, and I don't want to tread on any  
> > beliefs, but I just thought I'd offer a perspective from a fresh pair  
> > of eyes. Is there a serious movement to replace 'singleton'?
> 
> Some people want to change it, I think. If it must be changed, I  
> would favor something like "singular class" (and I agree with your  
> assessment of "ad hoc"). Some have suggested "eigenclass" -- and I  
> admit this is a cool-sounding word, reminding me of my math and physics  
> (and German) in college. But I can't really advocate it seriously.

Hal,

I think transfire (and rosco) were referring to singleton methods, not  
classes. And, actually I totally agree with the points made by rosco.  
'Ad hoc' has too many negative connotations and singleton has a fairly  
unambiguous meaning.

A singleton class should appear to the consumer as a regular class, but  
under the skin always return the same instance. How is this  
accomplished in Ruby? It couldn't be done in initialize, could it  
(because initialize doesn't actually return an instance)?

--Jonathan

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [6 December 2005 04:32 UTC](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980/20 "2005-12-06T04:32:33Z")

</div>

> 'Ad hoc' has too many negative connotations and singleton has a fairly  
> unambiguous meaning.

I felt the same way at first, until I started using it, keeping in mind  
the strict definition --even the Latin definition: \*for this\*.

T.

[Next page](https://rubytalk.org/t/injecting-dynamic-methods-into-a-class/22980.md?page=2)
