Skip to content

Commit

Permalink
Dynamically define functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Jan 9, 2012
1 parent f1dd547 commit 15c8df7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Makefile
Expand Up @@ -4,13 +4,13 @@ ERL=erl -noshell -pa $(EBIN_DIR)

.PHONY: setup test clean

compile: ebin src/dynamo_router_parser.erl

setup:
git submodule update --init
cd deps/ibrowse && make
cd deps/misultin && make

compile: ebin src/dynamo_router_parser.erl

src/dynamo_router_parser.erl: src/dynamo_router_parser.yrl
@ echo Compiling parser ...
$(ERL) -eval 'yecc:file("$<"), halt().'
Expand All @@ -19,6 +19,7 @@ src/dynamo_router_parser.erl: src/dynamo_router_parser.yrl
@ echo

ebin: lib/*.ex lib/*/*.ex lib/*/*/*.ex
@ rm -f ebin/::*.beam
@ echo Compiling ...
@ mkdir -p $(EBIN_DIR)
@ touch $(EBIN_DIR)
Expand Down
13 changes: 13 additions & 0 deletions examples/simple.exs
@@ -0,0 +1,13 @@
# Run this app with:
#
# elixir -pa ebin -pa deps/misultin/ebin examples/simple.exs

defmodule MyApp do
use Dynamo::App

get "/foo/bar" do

end
end

MyApp.run
8 changes: 8 additions & 0 deletions lib/dynamo.ex
@@ -1,2 +1,10 @@
defmodule Dynamo do
def run(name, options) do
options = Orddict.merge default_options_for(name), options
IO.puts "Running #{Orddict.fetch(options, :name, nil)} on #{Orddict.fetch(options, :port, nil)}"
end

defp default_options_for(name) do
[port: 3000, name: name]
end
end
38 changes: 38 additions & 0 deletions lib/dynamo/app.ex
@@ -0,0 +1,38 @@
defmodule Dynamo::App do
# Hook invoked when Dynamo::App is used.
# It initializes the app data, registers a
# compile callback and import Dynamo::DSL macros.
defmacro __using__(module) do
Module.merge_data module, routes: []
Module.add_compile_callback module, __MODULE__
quote { require Dynamo::DSL, import: true }
end

defmacro __compiling__(module) do
# Compile routes
routes = Orddict.fetch Module.read_data(module), :routes, []
Dynamo::Router.compile(module, routes)

# Clean up any internal state
# TODO: Use Module.remove_data once we add it to Elixir
Module.merge_data module, routes: []

# Generate both an service entry points
quote do
def run(options // []) do
Dynamo.run(__MODULE__, options)
end

def service(request, response) do
path = request.path
verb = request.request_method
case recognize_route(verb, path, []) do
match: { :ok, fun, _ }
apply __MODULE__, fun, [request, response]
match: :error
IO.puts "SERVE 404"
end
end
end
end
end
18 changes: 18 additions & 0 deletions lib/dynamo/dsl.ex
@@ -0,0 +1,18 @@
defmodule Dynamo::DSL do
defmacro route(verb, path, contents) do
list_path = to_list(path)
bin_path = to_binary(path)

quote do
path = unquote(list_path)
routes = Orddict.fetch Module.read_data(__MODULE__), :routes, []
name = :"_action_#{unquote(bin_path)}_#{length(routes)}"
Module.merge_data __MODULE__, routes: [{ path, {unquote(verb), name} }|routes]
def name, [request, response], [], unquote(contents)
end
end

defmacro get(path, contents) do
route(:GET, path, contents)
end
end
2 changes: 1 addition & 1 deletion lib/dynamo/router.ex
Expand Up @@ -10,7 +10,7 @@ defmodule Dynamo::Router do
}

contents = quote do
def recognize_route(verb, path, dict // 0) do
def recognize_route(verb, path, dict) do
_recognize_route_0(verb, Dynamo::Router::Parser.normalize(path), dict)
end
end
Expand Down

0 comments on commit 15c8df7

Please sign in to comment.