Preferred monkeypatching technique

On Jul 14, 2006, at 10:02 AM, Logan C. wrote:

  @@gensym_count += 1
  ("__gensym__%X" % @@gensym_count).intern
}

end
end

You don’t need a mutex.

class Symbol
@gensym_count = 0
def self.gensym
(“gensym%X” % @gensym_count += 1).intern
end
end


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On Jul 14, 2006, at 10:24 AM, Tom W. wrote:

module FormHelper
end
module X
def does_something(*options)
p options
end
end

module Y
def does_something(*options)
super(‘x’, *options)
end
end

class C
include X
include Y
end

C.new.does_something ‘foo’


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On Jul 14, 2006, at 1:34 PM, Eric H. wrote:

subclass doesn’t get me anywhere because the 3rd party app (i.e.
module ActionView
end
def does_something(*options)


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Rails does “funny” things. These helpers are usually used from within
eruby templates e.g:

<%= text_field( ... ) %>

Rails sets up the context in which the templates are executed. He’d
have to go into the actual rails source to fix this. OTOH…

Ok just as I thought, Rails is not this dumb

Tom just do

def text_field(*args)
orig_result = super
# modify orig result
end

in app/helpers/application_helper.rb

Or if you want it in a per controller bias app/helpers/
_helper.rb

No monkey-patching required

On Jul 14, 2006, at 1:26 PM, Eric H. wrote:

  @@gensym_count ||= 0

def self.gensym
(“gensym%X” % @gensym_count += 1).intern
end
end

Do you not need a Mutex now, since @gensym_count += 1 is
effectively atomic in current ruby, or will you never need a mutex?

What if?

thread 1:
@gensym_count += 1
thread 2:
@gensym_count += 1

thread 1:
interpolate and intern
thread 2
interpolate and intern

I guess it’s ok since a = expr is always supposed to return expr not
a, but it leaves a bad taste in my mouth.

On Jul 14, 2006, at 12:29 PM, Tom W. wrote:

You just described subclasses:
option to each form field helper (the ones that create
__classless_text_field(object_name, method, options.merge
end
include Y

Tom

Tom-

If you want to do that methodology in a plugin its as easy as

dropping this in the init.rb of a blank plugin:

ActionView::Base.class_eval do
def text_field(*args)
orig_result = super
# modify orig result
end
end

-Ezra

Tom W. wrote:

write some code that always adds a certain attribute to the options
wants to modify the same method (doing something similar to me) and just
so happens to also use :__old_put_out_fire as THEIR alias. Now we’ve got
my plugin’s method as the alias calling itself, which leads to, you
know, badness.

So I’m wondering if there’s a better way. Perhaps some way to turn
Firetruck into an ancestor of itself, so to speak, so that my plugin
would create a new Firetruck class, pushing the old Firetruck backward
in the chain and allowing me to call super instead and preventing
alias_method explosions. Or would that just end up causing more havoc?

Not a solution, but:

http://rcrchive.net/rcr/show/321

cut MyCut < Firetruck
def put_out_fire(options = {})
super(options.merge(:nozzle => :big))
end
end

(Trans, can I omit the `MyCut <’ part?)

Cheers,
Daniel

Daniel S. wrote:

happy to allow plugins to modify core code. Now, let’s say I want to
Which works just fine until someone else comes up with a plugin that

(Trans, can I omit the `MyCut <’ part?)
Sure. Although, the name provides a handle if you need to dynamically
effect the cut later --just like any Ruby class. But you can of course
do it annonymously too:

Cut.new(Firetruck) do

end

And if you make a module you can “preclude” (in contrast to include)

class FireTruck
preclude BigFireTruck
end

T.

Logan C. wrote:

that specifies an appropriate class (since CSS attribute selector
options.merge({:class => (options[:class].to_s + ’ text’).strip}))
end
end

Ok just as I thought, Rails is not this dumb
Or if you want it in a per controller bias
app/helpers/_helper.rb

No monkey-patching required

That’s quite true, it does work wonderfully in application_helper.rb.
Though there’s something nice about having the functionality reside in a
plugin, making it reusable in a nicer fashion. Thanks for the reminder!

Tom

[email protected] wrote:

end
end
would create a new Firetruck class, pushing the old Firetruck
p options
FireTruck.new.put_out_fire(1 => 2)
FireTruck.new.put_out_fire(1 => 2)

Output:

{1=>2, :nozzle=>“big”}
New version!
{1=>2, :nozzle=>“big”}

David

This is a bit unrelated, but is there a way to give the block parameter
of define_method a default (because otherwise you now have to send
put_out_fire at least an empty hash)?

define_method(:put_out_fire) do |options|
m.bind(self).call(options.merge({ :nozzle => “big” }))
end

Daniel S. wrote:

happy to allow plugins to modify core code. Now, let’s say I want to
Which works just fine until someone else comes up with a plugin that
more havoc?

(Trans, can I omit the `MyCut <’ part?)

Cheers,
Daniel

I looked at that RCR a while back, but only glanced over it as it was
not applicable to my situation at the time. Looking at it again, I see
the beauty and power in it. I would love to see that end up in 2.0!

Tom

On 7/14/06, Tom W. [email protected] wrote:

end
not applicable to my situation at the time. Looking at it again, I see
the beauty and power in it. I would love to see that end up in 2.0!

Tom

I can’t remember if I’ve posted this before, but here is my “poor
man’s cut” which might be handy in the meantime:

def cut(klass, &block)
klass = Object.send(:remove_const, klass.to_s)
Object.const_set(klass.to_s, Class.new(klass, &block))
end

class A
def hello
“hello”
end
end

a = A.new
puts a.hello

cut A do
def hello
“{” + super + “}”
end
end

b = A.new
puts b.hello

but beware - it only works on instances created ~after~ the cut

puts a.hello

END
hello
{hello}
hello

Regards,
Sean

Tom W. wrote:

Pretend Firetruck is in a 3rd party application (like Rails) that is

preventing alias_method explosions. Or would that just end up causing
end
not applicable to my situation at the time. Looking at it again, I see
the beauty and power in it. I would love to see that end up in 2.0!

+1

[email protected] wrote:

Pretend Firetruck is in a 3rd party application (like Rails) that is

alias_method explosions. Or would that just end up causing more havoc?
(Trans, can I omit the `MyCut <’ part?)

Sure. Although, the name provides a handle if you need to dynamically
effect the cut later --just like any Ruby class. But you can of course
do it annonymously too:

Cut.new(Firetruck) do

end

Neat-o.

How about a method-level shorthand?

class Firetruck
redef put_out_fire(options = {})
# maybe something other than “super”?
super(options.merge(:nozzle => :big))
end
end

That way you can also easily cut a class from within itself, even
conditionally.

Cheers,
Daniel

On Jul 14, 2006, at 10:57 AM, Logan C. wrote:

end

<%= text_field( ... ) %>

Rails sets up the context in which the templates are executed. He’d
have to go into the actual rails source to fix this. OTOH…

This is what ActionController::Base::helper is for.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Peña wrote:

fr hal:

Actually it was only last week that I first saw this term

being used in the Ruby community. I wonder if it’s too

late to squash it?

you took a vacation :wink:
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/9699d659bd806203

No, I saw that thread. But it was used in a Python
context there.

Now people are applying it to Ruby. That bothers me
a little.

Hal

On Jul 14, 2006, at 7:09 PM, Eric H. wrote:

module Helpers
end
super(‘x’, *options)
Rails does “funny” things. These helpers are usually used from

Did you miss the rest of my post where I told him to use helpers? Did
the ML slice that part off or something?

Eric H. [email protected] writes:

You don’t need a mutex.

class Symbol
@gensym_count = 0
def self.gensym
(“gensym%X” % @gensym_count += 1).intern
end
end

Okay, but now if two different files include this exact code, you’re
re-generating the same symbols. This is why I used ||=, making your
code:

class Symbol
@gensym_count ||= 0
def Symbol.gensym
(“gensym%X” % @gensym_count += 1).intern
end
end

At the very least, two people using the same exact code to define
gensym shouldn’t collide with each other.

Daniel M. wrote:

Okay, but now if two different files include this exact code, you’re
re-generating the same symbols. This is why I used ||=, making your
code:

class Symbol
@gensym_count ||= 0
def Symbol.gensym
(“gensym%X” % @gensym_count += 1).intern
end
end

What if the symbol is already used?

define_method( :__gensym__0 ) do

end

Symbol.gensym => :__gensym__0

I know, unlikley, but gensym’s return is not neccessarily unique.

T.

On Jul 15, 2006, at 9:37 AM, [email protected] wrote:

end

At the very least, two people using the same exact code to define
gensym shouldn’t collide with each other.

if two different files have this exact same code inlined the
programmer should be shot. if two different files require a third
that contains this code then there will be no problem.

Indeed, but I think you’re being too kind.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On Sat, 15 Jul 2006, Daniel M. wrote:

At the very least, two people using the same exact code to define
gensym shouldn’t collide with each other.

if two different files have this exact same code inlined the programmer
should
be shot. if two different files require a third that contains this code
then
there will be no problem.

2 cts.

-a