Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет peter_lemenkov ([info]peter_lemenkov) в [info]programming
@ 2006-10-19 22:23:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Цикл на Erlang'е
Приветствую!

Что-то я недопонял. Как заставить выполнить кусок кода, скажем, шесть раз.

Дано:

unixODBC, откуда я читаю записи вот так:

main_cycle (Ref) ->
	case odbc:select_count(Ref, "select A,B,C from name.table") of 
		{ok, NumberOfRows} ->
			if 
				NumberOfRows > 0 ->
					select_calls(Ref)
			end;
		Error -> 
			exit(Error)
	end.


В вышеуказанной функции я получаю NumberOfRows например равным шести. Я не нашел ничего лучше, как рекурсивно выполнить select_calls до тех пор, пока мне не сообщат об ошибке:

select_calls(Ref) ->
	case odbc:next(Ref) of 
		{selected,["CS_CALLED_STATION_ID","CS_CALLING_STATION_ID","CS_LOCALCALLID"], [{Caller,Called,SessionID}]} ->
			write_msg(Caller,Called,SessionID),
			select_calls(Ref);
	Error -> 
		io:format("end of data\n")
	end.


Запросить сразу лист записей, а потом сделать map или foreach нельзя, т.к. драйвер базы данных (Oracle) для unixODBC еще не дописан до конца (а фирменный от Oracle или другой коммерческий от Easysoft настолько проблемно ставится, что проще будет пока с этим повозиться) и не позволяет селектом выдавать сразу лист - только так, по одной записи.

Так вот, хотелось бы не дожидаться пока odbc:next выбросит ошибку, а выполнить его столько, сколько мне надо.

Как?
А то я что-то этот момент упустил пока. В туториалах есть много-много про параллельное программирование и кластеризацию ,а вот такой момент что-то обойдет вниманием.

Я хотел добавить лишний параметр в вызов функции, что-то вроде

select_calls(Ref, counter) ->
	if
		counter > 0 ->
			...
			select_calls(Ref, counter-1);
	end.


но это почему-то не работает.


(Добавить комментарий)


[info]potan
2006-10-20 12:25 (ссылка)
Странно, со вторым параметром должно работать.
А что с ним происходит?

(Ответить) (Ветвь дискуссии)


[info]peter_lemenkov
2006-10-21 13:46 (ссылка)
Я, по всей видимости, что-то упустил в синтаксисе. Вот я сделал тестовую программку:

-module(test).
-export([test_func/0]).
-export([test_recursion/2]).
        
test_func() ->
        test_recursion(1, 6).

test_recursion(X, N) ->
        if
                N > 0 ->
                        io:format("cycle! ~w ~n", [N]),
                        test_recursion(X,N-1)
                end.


И вот что получаю:

[petro@Sulaco erlang]$ erl
Erlang (BEAM) emulator version 5.5 [source] [async-threads:0] [hipe]

Eshell V5.5  (abort with ^G)
1> c(test).
{ok,test}
2> test:test_func().    
cycle! 6 
cycle! 5 
cycle! 4 
cycle! 3 
cycle! 2 
cycle! 1 

=ERROR REPORT==== 21-Oct-2006::13:40:58 ===
Error in process <0.32.0> with exit value: {if_clause,[{test,test_recursion,2},{shell,exprs,6},{shell,eval_loop,3}]}

** exited: {if_clause,[{test,test_recursion,2},
                       {shell,exprs,6},
                       {shell,eval_loop,3}]} **
3> 


А что не так у меня с if-выражением?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]peter_lemenkov
2006-10-21 13:49 (ссылка)
А! Понял.

Надо вот так:

-module(test).
-export([test_func/0]).
-export([test_recursion/2]).
        
test_func() ->
        test_recursion(1, 6).

test_recursion(X, N) ->
        if
                N > 0 ->
                        io:format("cycle! ~w ~n", [N]),
                        test_recursion(X,N-1);
                N == 0 ->
                        io:format("END cycle! ~w ~n", [N])
        end.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2006-12-09 18:32 (ссылка)
Гм... Это же всё-таки эрланг... На нём обычно пишут так:

test_recursion(X, 0) ->
io:format("END cycle! ~w ~n", [N]).

test_recursion(X, N) when N > 0 ->
io:format("cycle! ~w ~n", [N]),
test_recursion(X, N-1).

А в первом примере вместо count надо было писать Count...
Потому как в эрланге переменные обязаны быть с большой буквы...

(Ответить) (Уровень выше) (Ветвь дискуссии)

вот так:
(Анонимно)
2008-06-11 12:42 (ссылка)
%% повторить F N раз

repeat(N, F) -> repeat(1, N, F).
repeat(N, N, F) -> F();
repeat(I, N, F) -> F(), repeat(I+1, N, F).

(Ответить) (Уровень выше) (Ветвь дискуссии)

Re: вот так:
(Анонимно)
2011-09-01 10:56 (ссылка)
repeat(N, F)
when N>0 ->
F(), repeat(N-1, F);
repeat(N, F) -> ok.

(Ответить) (Уровень выше)