sm.run_sfi(dedent("""
macro drop _all
local local1 = 1
local local2 "two"
local local3 `""3""' """))
run_as_program_w_locals("""disp `"`local1' `local2' `local3'"' """)1 two "3"
We can run multi-line Stata code as a Stata program to prevent the echo of commands. But this approach requires special care for handling both local macros and valid Stata code that cannot be run inside a Stata program.
(Note: An alternative approach, prepending each Stata command with noisily and placing them inside a quietly block, was rejected at a certain point as more difficult overall, but it may be worth revisiting if unanticipated issues with the current run-as-program approach arise.)
We aim to run Stata code inside a Stata program, yet handling locals as if the code were run normally (rather than inside the program scope).
We accomplish this by first grabbing any previously-defined locals (with stata_more.get_local_dict) and artificially defining their values at the start of the program (using stata_more.locals_code_from_dict).
Then we also want to artificially transfer any locals created within the program to the outside scope. We do this by making the program an s-class program and storing any locals present at the end of the program via sreturn. These locals can then be quietly defined in the main scope after the program run has completed.
run_as_program_w_locals (std_code, local_dict=None)
sm.run_sfi(dedent("""
macro drop _all
local local1 = 1
local local2 "two"
local local3 `""3""' """))
run_as_program_w_locals("""disp `"`local1' `local2' `local3'"' """)1 two "3"
code = '''\
local test1 "blah blah"
local test2 "blah"
'''
run_as_program_w_locals("""disp `"`local1' `local2' `local3'"' \n""" + code)
test_eq(sm.get_local_dict(),
{'test2': 'blah',
'test1': 'blah blah',
'local1': '1',
'local2': 'two',
'local3': '"3"'})1 two "3"
run_non_prog_noecho (std_non_prog_code, run_as_prog=<function run_as_program_w_locals>)
We remove comments from single-line code to avoid the error that would otherwise result.
Certain valid Stata code (referred to here as prog_code because it defines Stata programs–or runs mata or python code blocks) cannot be run inside a Stata program, so we need to identify such code and run it separately.
run_prog_noecho (std_prog_code)
Other programs (that is, Stata’s program define, as well as mata or python blocks) cannot be defined/run within a Stata program, however. Instead, we will just run them directly, quietly to prevent echo, except for the case of mata programs, in which case quietly would block the output.
prog_block_code = dedent("""\
program define display1
disp "display1 output"
end
""")
run_prog_noecho(prog_block_code)
run_single("display1")
display1 output
hello
. mata:
------------------------------------------------- mata (type end to exit) -----
: display("hello")
hello
: end
-------------------------------------------------------------------------------
.
run_noecho (code, sc_delimiter=False, run_as_prog=<function run_as_program_w_locals>)
After break_out_prog_blocks, run each prog and non-prog block noecho
run_noecho(dedent('''\
capture program drop ender
program define ender
disp "ender output"
end
capture program drop display2
program define display2
ender
end
display2
'''))
ender output
run_noecho(dedent("""\
disp `"`local1' `local2' `local3'"'
disp `"`local1' `local2' `local3' `test1'"'
"""), run_as_prog=run_as_program_w_locals)1 two "3"
1 two "3" blah blah
code = """\
local local1 "foo"
local local2 "bar"
local abcd "foo bar"
"""
run_noecho(code, run_as_prog=run_as_program_w_locals)
run_noecho(dedent("""\
disp `"`local1' `local2' `local3'"'
disp `"`local1' `local2' `local3' `test1'"'
"""), run_as_prog=run_as_program_w_locals)foo bar "3"
foo bar "3" blah blah
(1978 automobile data)
Price
-------------------------------------------------------------
Percentiles Smallest
1% 3291 3291
5% 3748 3299
10% 3895 3667 Obs 74
25% 4195 3748 Sum of wgt. 74
50% 5006.5 Mean 6165.257
Largest Std. dev. 2949.496
75% 6342 13466
90% 11385 13594 Variance 8699526
95% 13466 14500 Skewness 1.653434
99% 15906 15906 Kurtosis 4.819188