Is there an easy way to interactively try redis_scan and the resulting LazyList from the command line?

I’ve been interactively trying out the Redis client and want to use redis_scan, but that returns a LazyList.
What I don’t know is if there’s a way on the Prolog command line to call
redis_scan(default, X, pattern("*"))
where I save the instantiated variable X so I can then interactively call NEXT on it a few times?

The only way I can think of was to call
redis_scan(default, X, pattern("*")), lazy_list_materialize(X).

but that doesn’t let me interact with it.

You can access variables in the top level like this:

1 ?- A=swipl_is_great.
A = swipl_is_great.

2 ?- writeln($A).
swipl_is_great
A = swipl_is_great.

Hope this helps.

Yeah, but I don’t know any syntax that lets me call redis_scan(default, X, pattern("*")) and assign the returned X to a variable.

Like this? No that I really see the point why you would want this …

60 ?- redis_scan(default, X, [pattern("*")]).
lazy_list(redis:scan_next(s(scan, default, 0, [])), X).

61 ?- member(E, $X).
E = 'swish:chat:visitor:586ca4a0-2593-11eb-85be-effdc2ec0b9d',
X = ['swish:chat:visitor:586ca4a0-2593-11eb-85be-effdc2ec0b9d', 'swish:stat:peter', 'swish:http:session:session:0e21-3ceb-80d3-6d2d.janw', 'swish:stat:localhost:3050', 'swish:chat:session:586c6abc-2593-11eb-aefa-83ef365663e9', 'swish:http:session:data:0e21-3ceb-80d3-6d2d.janw', 'swish:http:session:expire', 'swish:gitty:head'] ;
E = 'swish:stat:peter',
X = ['swish:chat:visitor:586ca4a0-2593-11eb-85be-effdc2ec0b9d', 'swish:stat:peter', 'swish:http:session:session:0e21-3ceb-80d3-6d2d.janw', 'swish:stat:localhost:3050', 'swish:chat:session:586c6abc-2593-11eb-aefa-83ef365663e9', 'swish:http:session:data:0e21-3ceb-80d3-6d2d.janw', 'swish:http:session:expire', 'swish:gitty:head'] ;
...

I actually thought that once a predicate call returned to the command line that any variables in that call were lost, had no knowledge of the $syntax - glad I know it now, thanks!

Normally, and in most Prolog systems that is true. There was a time before copy/paste and there was xpce that returned objects as @12345678 terms and it was a bit too tedious to retype all that :slight_smile: It is still a practical feature though as not all terms can be serialized these days. Think blobs. Cyclic terms and attributed variables can also be problematic.

Note that to avoid blowing up memory usage really large terms are not saved. There is a flag toplevel_var_size to control this.

I’ve got several redis write calls in a row and want to use a redis transaction to group them, but two of them are calls to redis_set_hash/3 where I have a Dict to pass in):

redis_set_hash(default, MacKey, Dict),
redis_set_hash(default, NameKey, Dict),
redis(default, sadd(LocationKey, Hostname),_),
redis(default, sadd(CategoryKey, Hostname),_),

is there a form of redis_set_hash/3 which can be part of a list in:

redis(default,
[   multi,
      ?,
      ?,
      sadd(LocationKey, Hostname),
      sadd(CategoryKey, Hostname),
      exec
     ]
     ).

Unless you have a non-prolog redis client, then it would be better to store the dict as a prolog term; if you need to store the dict as a redis hash then you can use a helper predicate like this:

redis_dictset_cmd(Key, Dict, Cmd) :-
   redis_array_dict(List,_,Dict),
   Cmd =.. [hset|[Key|List]],
   format('redis hset cmd is: ~w~n',[Cmd]).

test_hash :-
   redis_dictset_cmd(mykey1,_{field11: v1, field12: v2},SetHash1),
   redis_dictset_cmd(mykey2,_{field21: v3, field22: v4},SetHash2),
   redis(  default,
           [  multi,
	      SetHash1,
	      SetHash2,
	      exec
	   ]),
   show(hashes).

test_prolog_term :-
   Dict1 =_{field11: v1, field12: v2},
   Dict2 =_{field21: v3, field22: v4},
   redis(  default,
           [  multi,
	      set(mykey1,Dict1 as prolog),
	      set(mykey2,Dict2 as prolog),
	      exec
	   ]),
   show(dicts).

show(hashes) :-
   redis_get_hash(default, mykey1, Dict1),
   redis_get_hash(default, mykey2, Dict2),
   print_term(Dict1,[]), nl,
   print_term(Dict2,[]).

show(dicts) :-
   redis(default, get(mykey1), Dict1),
   redis(default, get(mykey2), Dict2),
   print_term(Dict1,[]), nl,
   print_term(Dict2,[]).

Query:

10 ?- test_hash.
redis hset cmd is: hset(mykey1,field11,v1,field12,v2)
redis hset cmd is: hset(mykey2,field21,v3,field22,v4)
_{field11:v1,field12:v2}
_{field21:v3,field22:v4}
true.

11 ?- test_prolog_term.
_{field11:v1,field12:v2}
_{field21:v3,field22:v4}
true.

Thanks, and yes I am planning to use redis to share data between Prolog and other languages, so I’m trying to only use native redis datatypes for now.

Part of my post was to suggest that maybe the ability to use redis_set/get_hash as part of a transaction should be part of the supplied redis library since as far as I understand transactions are a fairly common redis use case.

1 Like