I have a small logic, that alows I18n 'inplace translation' with AJAX, directly on the page. Therefore I want to intercept I18n.translate
My investigations brought me to this - nice and clean looking - logic: based on this SO Answer (Method Wrapping) and some "how could it work" trial and errors
module I18n
extend Module.new {
old_translate=I18n.method(:translate)
define_method(:translate) do |*args|
InplaceTrans.translate(old_translate,*args)
end
alias :t :translate
}
end
and
module InplaceTrans
extend Module.new {
def translate(old_translate,*args)
Translator.new.translate(old_translate, *args)
end
}
end
the Translator.new.translate() is just a Trick, so i dont have to restart rails server when developing
All above is working fine and stable, but i don't realy know what I am doing ...
Question(s):
Is this a valid (and clean) approach?
What does the extend Model.new { ... } do?
what is the difference to extend Model.new DO ... END? (seems to do nothing in my case)
EDIT: answerd my self: according to DO/END vs {} and at end of question:
And why does InplaceTrans.translate inside I18n.newly_defined_method() resolve to my anonymous module.translate according to this:
Creates a new anonymous module. If a block is given, it is passed the module object, and the block is evaluated in the context of this module using module_eval.
So it works, but i realy would like to know why!
(RoR 1.9.3,3.2)
EDIT: partial answer
extend Module.new {} evolves to extend(Module.new {})
whereas
extend Module.new do/end evolves to extend(Module.new) do/end
so with do/end the block is bound to result of extend. if you want to use do/end you must use braces:
extend(Module.new do/end) same as extend Module.new {}
The following is, what I figgured out, I dont know if there are other (side) effects I do not know.
lets start with a module:
module NiceOne
def self.init_param(param)
@base_param=param
end
def self.read_param
@base_param
end
def util_func(in_string)
in_string+NiceOne.read_param
end
end
and lets include it in a Class.
class HomeController < SiteController
...
include NiceOne
def sandbox
NiceOne.init_param(' the base param')
# later:NiceOne.write_other_param(' the other param')
puts NiceOne.read_param
#later: puts NiceOne.read_other_param
puts util_func('can we read')
end
end
so util_func 'moves' into HomeController, whereas the 'selfed methods' do not, we all know that (or not); so we get:
the base param
can we rad the base param
if you now extend NiceOne "manually" like that:
module NiceOne
def self.write_other_param(param)
@base_param=param
end
def self.read_other_param
@base_param
end
end
and uncomment the two lines in HomeController you get:
the other param
the other param
can we read the other param
So far so easy, and not the answer to the question, just intro
It would not be Ruby, if there wasn't a more elegant way to to this:
we keep the HomeController and NiceOne (original) untouched, but change the manual 'extend' to:
module NiceOneNicen
def write_other_param(param)
@base_param=param
end
def read_other_param
@base_param
end
end
module NiceOne
extend NiceOneNicen
end
and we get the same Output as before. The two methods 'move' into (extend) OneNice like utli_func into HomeController. And this is usefull, if you want to extend more than one module with your beloved module!
But if we need that only once? Dont polute Namespace, we create the module on the fly, i.e Module.new. So
module NiceOne
dummy=Module.new {
def write_other_param(param)
...
end
}
extend dummy
end
and finaly
module NiceOne
extend Module.new {
def write_other_param(param)
...
end
}
end
And if do/end is asked, we can use it, if we dont forget the braces ...
module NiceOne
extend( Module.new do
def write_other_param(param)
...
end
end)
end
so - to answer the last question: the anonymous module created with Module.new "exists only a short time" and is only used tu push its methods into OneNice
so you can read the
extend Module.new { .. }
like
"put a self. before every method in following" { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With