Hi Scott-
Here's a bugfix for one of the examples:
proc ds2;
data test(overwrite=yes);
declare char(10) name;
declare double age;
declare char(1) sex;
method init();
declare package hash h();
h.defineKey('name');
h.defineData('age');
h.defineData('sex');
h.dataset(%tslit({select * from class where sex='F'}));
/* h.dataset({select * from class where sex='F'}); */
h.defineDone();
end;
enddata;
run;
quit;
The fix was to add single quotes outside the brackets inside the h.dataset() query. Actually, since your query contains single quotes in one of the clauses, you can't add quotes because this messes up the syntax parser. So you have to use the %TSLIT() function as per Solutions for missing DATA step features within DS2.
Now a solution to get the variable attributes into the hash without needing to explicitly define their type:
/* Create an empty class that just has the variable we need */
data skeleton_class;
if _n_=0 then
set class(keep=name age sex);
run;
/*
Create a copy of the original data set. Apparently there is a
lock error if the same class is used in the h.dataset() statement
and the SET statement in the run() method. I tried creating this
with the /view option, but there was still a lock error.
A waste of resources, but maybe there is a work-around?
*/
data class_copy;
set class;
run;
proc ds2 ;
data test(overwrite=yes);
declare package hash h();
declare double rc;
method init();
if 0 then
set skeleton_class;
h.defineKey('name');
h.defineData('name');
h.defineData('age');
h.defineData('sex');
h.dataset(%tslit({select * from class where sex='F'}));
h.defineDone();
end;
method run();
set class_copy(keep=(name));
rc=h.find();
if rc ne 0 then
do;
age=-1;
sex='X';
end;
end;
enddata;
run;
quit;
Produces as a test data set:
One thing I've observed with DS2 is that the DECLARE statements need to appear at the top of the method. So this example you gave wouldn't work:
method init();
if 0 then set class (keep=(name age sex));
declare package hash h( [name], [age sex], 16, {select name, age, sex from
work.class where sex='F'} );
end;
, regardless of the other issues, because the hash package declaration appears after the IF statement. That's why I moved it to appear before the init() method. Also I think it needs to be declared outside the methods in order for it to be available to both init() and run().
... View more