Monkeypatching for a local method in Rails 3 - ruby-on-rails-3

I have a situation like below:
Module Task
def get(a)
fetch(a)
end
def fetch(a)
query(a)
end
def query(a)
puts a
end
end
and only get method is called from outside of module like
Task.get('name')
I want to monkey patch only method query to make some change in response of get method since it calls query intern.
Please suggest a way to do this.

In order to monkey patch in cases like these, we need to include a file in lib folder. In this case you need to make a file inside lib folder of the same name. In that first include the module TASK and then use MODULENAME.module_eval and add the methods in this. In this file u can override the methods in the actual module and add methods to it too.
In order for this to work you will have to require the file u created in lib in config/initializers/app.rb
Incase the module you are over riding is present inside a folder (like in case of a ruby gem) you need to include the whole path. For ex.
Module_1.Module_2.module_eval
where module 2 is inside module 1.

Related

How to declare module_name in groups Odoo

I used this code in a xml view in ideas_app module:
groups="group_vote_user"
but i got this error "External ID must be fully qualified"
Is it really need module name like groups="ideas_app.group_vote_user" even this view in same module with group_vote_user security (in module ideas_app)?
Is there any ways to not declare module name or change with this.group_vote_user like that?
I think, you need to check sequence of files in manifest file. For example, security.xml should be come first and then others view files.
I am not sure if there is a way to change it. But as per standards, we need to follow standard way like "module_name.xml_ID"

Elixir - Call method on module by String-name

I'm pretty new to Elixir and functional programming-languages in general.
In Elixir, I want to call one specific function on Modules, given the Module name as String.
I've got the following (very bad) code working, which pretty much does what I want to:
module_name = elem(elem(Code.eval_file("module.ex", __DIR__), 0), 1)
apply(module_name, :helloWorld, [])
This (at least as I understand it) compiles the (already compiled) module of module.ex in the current directory. I'm extracting the modules name (not as a String, don't know what data-type it actually is) out of the two tuples and run the method helloWorld on it.
There are two problems with this code:
It prints a warning like redefining module Balance. I certainly don't want that to happen in production.
AFAIK this code compiles module.ex. But as module.ex is already compiled and loaded, it don't want that to happen.
I don't need to call methods on these modules by filename, the module-name would be ok too. But it does have to by dynamic, eg. entering "Book" at the command line should, after a check whether the module exists, call the function Book.helloWorld.
Thanks.
Well, thats where asking helps: You'll figure it out yourself the minute you ask. ;)
Just using apply(String.to_existing_atom("Elixir.Module"), :helloWorld, []) now. (maybe the name "Module" isn't allowed, don't know)
Note that you always need to prefix your modules with "Elixir."
defmodule Test do
def test(text) do
IO.puts("#{text}")
end
end
apply(String.to_existing_atom("Elixir.Test"), :test, ["test"])
prints "test"
and returns {:ok}
Here is a simple explanation:
Assuming that you have a module like this:
defmodule MyNamespace.Printer do
def print_hello(name) do
IO.puts("Hello, #{name}!")
end
end
Then you have a string that hold the module name that you can pass around in your application like this:
module_name = "Elixir.MyNamespace.Printer"
Whenever you receive the string module_name, you can instantiate a module and call functions on the module like this:
module = String.to_existing_atom(module_name)
module.print_hello("John")
It will print:
Hello, John!
Another way to dynamically call the function MyNamespace.Printer.print_hello/1 is:
print_hello_func = &module.print_hello/1
print_hello_func.("Jane")
It will print:
Hello, Jane!
Or if you want to have both module_name as atom and function_name as atom, and pass them around to be executed somewhere, you can write something like this:
a_module_name = :"Elixir.MyNamespace.Printer"
a_function_name = :print_hello
Then whenever you have a_module_name and a_function_name as atoms, you can call like this:
apply(a_module_name, a_function_name, ["Jackie"])
It will print
Hello, Jackie!
Of course you can pass module_name and function_name as strings and convert them to atoms later. Or you can pass module name as atom and function as a reference to function.
Also note that the name of a module is an atom so doing String.to_existing_atom isn't usually needed. Consider this code:
defmodule T do
def first([]), do: nil
def first([h|t]), do: h
end
In this case you can simply do the apply in this fashion:
apply(T,:first,[[1,2,3]])
#=> 1
Or this example (List below is the Elixir List module):
apply(List,:first,[[1,2,3]])
#=> 1
I mean to say that if you know the name of the module, it's not necessary to pass it as a string and then convert the string to an existing atom. Simply use the name without quotation marks.

How to allow access to group of generated sub trees in web.config using RegEx?

Here is what I need to do:
In my CodeIgniter application, I have a folder named "modules", and each module contains (among others) a folder named assets, which contains all the resources that need to be available from the browser.
The file structure is in this format:
modules
MyModule
assets
views
etc...
The MyModule folder is dynamic, so I need to add a rule that does not rewrite the paths like
/modules/ANY MATCH/assets
but I can't figure out the proper Regular Expression...
My current pattern is the following:
^(index\.php|robots\.txt|libs|themes|app/modules/^.$/assets|sitemap.xml)
but the ^.$ obviously doesn't work... I'm a complete RegEx noob :/
Any help would be appreciated. Thanks for your time!
I think you want
^(index\.php|robots\.txt|libs|themes|app/modules/.*/assets|sitemap\.xml)
or better, if ANY MATCH is always a single folder only:
^(index\.php|robots\.txt|libs|themes|app/modules/[^/]*/assets|sitemap\.xml)

Rails 3 with Liquid Custom Tags not found

I am trying to create a set of custom tags for some liquid templates using Rails 3. I added a 'liquid_tags.rb' in my lib/ directory with content like this:
class UserControls < Liquid::Tag
def initialize(tag_name)
super
end
def render(context)
tag = "<b>TAG</b>"
end
end
Liquid::Template.register_tag('user_controls', UserControls)
When I try to get the tag in my view via '{% user_controls %}' it tells me the tag isn't found.
Any ideas?
Thanks in advance.
That's right, as marcusmateus says, Rails won't load anything in the lib directory automatically even if you have added it to the autoload_paths unless the class or module name inside the file matches the file name.
To sort this problem just put the custom formatters inside the lib directory, each in their own file (I tried using a module to wrap them all up but no luck)
class MyCustomTag < Liquid::Tag
def initialize(tag_name, params, tokens)
# do something
end
def render(context)
# do something
end
end
Then created an initializer (in config/initializers) responsible for registering the custom tags with Liquid. i.e.
Liquid::Template.register_tag('custom_tag', MyCustomTag)
Liquid::Template.register_tag('custom_tag', MyCustomTag2EtcEtc)
Are you sure that file is getting loaded? If it's not, then register_tag is never getting called. I would throw in a puts statement above register_tag to debug it, make sure that the file is actually being loaded. You may to move the register_tag into an initializer
on config/application.rb try adding this line
config.autoload_paths << File.join(config.root, "lib")
I believe files are only autoloaded if the name of the file matches the name of the class it contains. In the question you state that your file is named 'liquid_tags.rb', but your class is named UserControls... if you rename your filed 'user_controls.rb' it should begin autoloading.
I think it's not loading problem -- I have it also. The tag is being loaded, you can print the current registered tags:
Liquid::Template.tags.inspect

Lua - Question on modules

Say I want to make a module for say a set of GUI controls, how would I create a module that would load all of the GUI scripts, and should I put those scripts as modules themselves? I was thinking of having a system like this:
module("bgui", package.seeall)
dofile("modules/bgui/control.lua")
dofile("modules/bgui/container.lua")
dofile("modules/bgui/screenmanager.lua")
dofile("modules/bgui/form.lua")
dofile("modules/bgui/button.lua")
dofile("modules/bgui/textbox.lua")
dofile("modules/bgui/label.lua")
Would all the files run then have the variables they set as part of the bgui module?
Aka if in control.lua I had control = {...} would it be defined as bgui.control or should I make the control.lua a module itself, something like module("bgui.control") would that work as I intend?
Sorry if this isn't very clear had to write it in a rush, thanks :)
You are actually asking two questions here:
First, "is this way of loading lots of files on a module ok?"
The answer is - yes. It is kind of an unspoken standard to call that file mymodule/init.lua. Most people have ?/init.lua included on their path, so you can just write require('modules/bgui') and init.lua will be loaded automatically.
This said, you might want to remove some code duplication by using a temp table and a loop:
# modules/bgui/init.lua
local files = {
'control', 'container', 'screenmanager', 'form', 'button', 'textbox', 'label'
}
for _,file in ipairs(files) do dofile("modules/bgui/" .. file .. ".lua") end
Second, "are objects defined on one file available on bgui?".
The answer is also yes, as long as the file defining the variable is "done" (with dofile or require) before the file using the variable.