metafunctions in controllers

1 view
Skip to first unread message

jm

unread,
Aug 14, 2007, 2:02:43 AM8/14/07
to erl...@googlegroups.com
Is there a way to have meta-methods or -functions in controllers? What
I'm looking for is something similar to ruby's missing_method().


Jeff.

Yariv Sadan

unread,
Aug 14, 2007, 3:52:05 AM8/14/07
to erl...@googlegroups.com
It looks like erlang:process_flag may do the trick. From the docs:

process_flag(error_handler, Module)
This is used by a process to redefine the error handler for undefined
function calls and undefined registered processes. Inexperienced users
should not use this flag since code autoloading is dependent on the
correct operation of the error handling module.

You can give it a try, but it looks risky.

BR,
Yariv

jm

unread,
Aug 14, 2007, 4:13:10 AM8/14/07
to erl...@googlegroups.com
Yariv Sadan wrote:
> It looks like erlang:process_flag may do the trick. From the docs:
>
> process_flag(error_handler, Module)
> This is used by a process to redefine the error handler for undefined
> function calls and undefined registered processes. Inexperienced users
> should not use this flag since code autoloading is dependent on the
> correct operation of the error handling module.
>
> You can give it a try, but it looks risky.


Seems, after some reading, I'd have to write a new error_handler and in
particular redefine the function error_handler:undefined_function/3.
There appears to be lot of warnings attached to attempting any of this.
Not something I was to do at the moment. I thought there might have been
something in erlyweb that give the ability to define a "default" action.
Say for example I have the URL of the form
http://server/model/method/param if someone submits a request to
http://server/model/param I'd like to map the latter to the former where
method becomes some default action like view. For example,
http://beerriot.com/beer/737 would give the same result as
http://beerriot.com/beer/view/737.

Other than that and a few other bits and pieces erlyweb's looking good.
What format do you prefer patches to be in and against what (branch or
release)?

Jeff.

Yariv Sadan

unread,
Aug 14, 2007, 1:19:11 PM8/14/07
to erl...@googlegroups.com
There is a way of doing this now, though it's a bit indirect: Use
erlyweb_util:indexify(A, ["beer"]) in your app controller. Now all
requests to beerriot.com/beer will go to beer_controller:index(), so
you can write any logic you want in index() to process the list of
parameters. Does that work for you?

BR,
Yariv

jm

unread,
Aug 15, 2007, 9:00:56 AM8/15/07
to erl...@googlegroups.com
Yariv Sadan wrote:
> There is a way of doing this now, though it's a bit indirect: Use
> erlyweb_util:indexify(A, ["beer"]) in your app controller. Now all
> requests to beerriot.com/beer will go to beer_controller:index(), so
> you can write any logic you want in index() to process the list of
> parameters. Does that work for you?
>
> BR,
> Yariv


Should do except that I couldn't get it to work so I started to play
with the erlyweb source code. Ended up with the following changes

diff -Naur erlyweb-0.6.1.orig/src/erlyweb/erlyweb.erl
erlyweb-0.6.1/src/erlyweb/erlyweb.erl
--- erlyweb-0.6.1.orig/src/erlyweb/erlyweb.erl Sat Aug 11 23:02:58 2007
+++ erlyweb-0.6.1/src/erlyweb/erlyweb.erl Wed Aug 15 13:37:22 2007
@@ -401,10 +403,18 @@
end,
{page, Path};
{error, no_such_function} ->
- exit({no_such_function,
- {ComponentStr, FuncStr, length(Params),
- "You tried to invoke a controller function that doesn't "
- "exist or that isn't exported"}});
+ try
+ Controller = list_to_atom(ComponentStr ++ "_controller"),
+ Controller:get_ewc(ComponentStr, FuncStr, Params, AppData)
+ catch
+ %% catch the case of get_ewc not being defined and
+ %% take default action of exit({no_function...})
+ error:undef ->
+ exit({no_such_function,
+ {ComponentStr, FuncStr, length(Params),
+ "You tried to invoke a controller function
that does
n't "
+ "exist or that isn't exported"}})
+ end;
{ok, Component} ->
Component
end.

Then in the model

get_ewc(ComponentStr, FuncStr, [A |B] = _Params, _AppData) ->
io:format("***** hello from controller~n"),
NewParams = [ A | [ FuncStr | B]],
{ewc, model_controller, model_view, show, NewParams}.


This has the desired effoct. This works when the parameter refers to a
record that exists, when the data doesn't this I get one of two errors,
but I think this is my controller code.

I don't think this is an optimal solution as using this form I should be
able to return any valid {ewc, ...} construct from the contraller. It
doesn't appear this is possible at this point in the code. Which seems
to imply that the error should be propagated up and handled elsewhere.
Given a chance I'll take a look at it again tomorrow.

There's also a couple of modifications I made to add previous and next
links to the default list view which are currently hiding on a different
machine somewhere.

Jeff.

Yariv Sadan

unread,
Aug 17, 2007, 2:02:57 AM8/17/07
to erl...@googlegroups.com
I like the approach in principle, and I agree the error should be
propagated up. Ideally, controllers would be able to define a function
such as

catch_all(FuncName, Params) ->
%% return any controller return value


ErlyWeb would attempt to call this function when the client requests
an unidentified function from the controller.

Yariv

Reply all
Reply to author
Forward
0 new messages