Skip to content

Commit ecc88b9

Browse files
authored
Tests without Pluto (#9)
* Update runtests.jl * no need pluto * ref any * comment * bump version
1 parent ac17156 commit ecc88b9

File tree

5 files changed

+400
-313
lines changed

5 files changed

+400
-313
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PlutoHooks"
22
uuid = "0ff47ea0-7a50-410d-8455-4348d5de0774"
33
authors = ["Paul Berg <[email protected]>", "Michiel Dral <[email protected]>"]
4-
version = "0.0.4"
4+
version = "0.0.5"
55

66
[deps]
77
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

src/notebook.jl

Lines changed: 131 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
### A Pluto.jl notebook ###
2-
# v0.17.3
2+
# v0.18.1
33

44
using Markdown
55
using InteractiveUtils
@@ -31,6 +31,72 @@ There is a lot you can do with this, but some examples:
3131
You need to use Pluto version >= 0.17.2.
3232
"""
3333

34+
# ╔═╡ bc0e4219-a40b-46f5-adb2-f164d8a9bbdb
35+
"""
36+
@use_memo(deps::Vector{Any}) do
37+
# Expensive computation/loading
38+
end
39+
40+
Does a computation only when the deps array has changed.
41+
This is useful for heavy computations as well as resource fetches like file reading or fetching from the network.
42+
43+
```julia
44+
# Only read a file once
45+
@use_memo([filename]) do
46+
read(filename)
47+
end
48+
```
49+
50+
```julia
51+
@use_memo([a, b]) do
52+
a + b # But they're like really big numbers
53+
end
54+
```
55+
"""
56+
macro use_memo(f, deps)
57+
quote
58+
ref = @use_ref(nothing)
59+
if @use_did_deps_change($(esc(deps)))
60+
ref[] = $(esc(f))()
61+
end
62+
ref[]
63+
end
64+
end
65+
66+
# ╔═╡ 0f632b57-ea01-482b-b93e-d69f962a6d92
67+
md"""
68+
## Not really hooks but internally very hook-ish
69+
70+
These are all for making sure you have some level of Pluto-ness active. These are made to work outside of Pluto as well, but obviously give you the opposite results :P
71+
"""
72+
73+
# ╔═╡ 8c2e9cad-eb63-4af5-8b52-629e8d3439bd
74+
"""
75+
is_running_in_pluto_process()
76+
77+
This doesn't mean we're in a Pluto cell, e.g. can use @bind and hooks goodies.
78+
It only means PlutoRunner is available (and at a version that technically supports hooks)
79+
"""
80+
function is_running_in_pluto_process()
81+
isdefined(Main, :PlutoRunner) &&
82+
# Also making sure my favorite goodies are present
83+
isdefined(Main.PlutoRunner, :GiveMeCellID) &&
84+
isdefined(Main.PlutoRunner, :GiveMeRerunCellFunction) &&
85+
isdefined(Main.PlutoRunner, :GiveMeRegisterCleanupFunction)
86+
end
87+
88+
# ╔═╡ df0645b5-094a-45b9-b72a-ab7ef9901fa1
89+
"""
90+
is_inside_pluto(mod::Module)
91+
92+
This can be useful to implement the behavior for when the hook is called outside Pluto but in the case where Pluto **can** be loaded.
93+
"""
94+
function is_inside_pluto(mod::Module)
95+
# Note: this could be moved to AbstractPlutoDingejtes
96+
startswith(string(nameof(mod)), "workspace#") &&
97+
isdefined(mod, Symbol("@bind"))
98+
end
99+
34100
# ╔═╡ c82c8aa9-46a9-4110-88af-8638625222e3
35101
"""
36102
@use_ref(initial_value::Any)::Ref{Any}
@@ -40,6 +106,15 @@ Creates a Ref that is stable over multiple **implicit** runs of the cell. Implic
40106
This is useful to keep state around between runs.
41107
"""
42108
macro use_ref(initial_value=nothing)
109+
if !is_inside_pluto(__module__)
110+
ref = Ref{Any}()
111+
return quote
112+
ref = $(ref)
113+
ref[] = $(esc(initial_value))
114+
ref
115+
end
116+
end
117+
43118
ref_ref = Ref(Ref{Any}())
44119

45120
quote
@@ -103,6 +178,12 @@ end
103178
```
104179
"""
105180
macro use_state(initial_value)
181+
if !is_inside_pluto(__module__)
182+
return quote
183+
($(esc(initial_value)), x -> nothing)
184+
end
185+
end
186+
106187
quote
107188
rerun_cell_fn = @give_me_rerun_cell_function()
108189
state_ref = @use_ref($(esc(initial_value)))
@@ -131,6 +212,38 @@ macro use_state(initial_value)
131212
end
132213
end
133214

215+
# ╔═╡ cd048a16-37f5-455e-8b6a-c098d5f83b96
216+
"""
217+
@use_deps(deps::Vector) do
218+
# ... others hooks ...
219+
end
220+
221+
Experimental function to wrap a bunch of macros in a fake cell that fully refreshes when the deps provided change. This is useful if you make a macro that wraps a bunch of Pluto Hooks, and you just want to refresh the whole block when something changes. This also clears [`@use_ref`](@ref)'s and [`@use_state`](@ref)'s, even though these don't even have a deps argument.
222+
223+
Not entirely sure how much this is necessary (or if I'm missing something obvious that doesn't make it necessary).
224+
225+
Also, this name does **not** spark joy.
226+
"""
227+
macro use_deps(fn_expr, deps)
228+
if !is_inside_pluto(__module__)
229+
return quote
230+
$(esc(deps))
231+
232+
$(esc(fn_expr))()
233+
end
234+
end
235+
236+
cell_id_ref = Ref{UUID}(uuid4())
237+
238+
quote
239+
if @use_did_deps_change($(esc(deps)))
240+
$cell_id_ref[] = uuid4()
241+
end
242+
243+
with_cell_id($(esc(fn_expr)), $cell_id_ref[])
244+
end
245+
end
246+
134247
# ╔═╡ 89b3f807-2e24-4454-8f4c-b2a98aee571e
135248
"""
136249
@use_effect(deps::Vector{Any}) do
@@ -165,6 +278,13 @@ end
165278
```
166279
"""
167280
macro use_effect(f, deps)
281+
if !is_inside_pluto(__module__)
282+
return quote
283+
$(esc(deps))
284+
$(esc(f))()
285+
end
286+
end
287+
168288
# For some reason the `cleanup_ref` using @use_ref or assigned outside the
169289
# `register_cleanup_fn() do ... end` (and not interpolated directly into it)
170290
# is `nothing` when the cleanup function actually ran...
@@ -192,37 +312,8 @@ macro use_effect(f, deps)
192312
end
193313
end
194314

195-
# ╔═╡ bc0e4219-a40b-46f5-adb2-f164d8a9bbdb
196-
"""
197-
@use_memo(deps::Vector{Any}) do
198-
# Expensive computation/loading
199-
end
200-
201-
Does a computation only when the deps array has changed.
202-
This is useful for heavy computations as well as resource fetches like file reading or fetching from the network.
203-
204-
```julia
205-
# Only read a file once
206-
@use_memo([filename]) do
207-
read(filename)
208-
end
209-
```
210-
211-
```julia
212-
@use_memo([a, b]) do
213-
a + b # But they're like really big numbers
214-
end
215-
```
216-
"""
217-
macro use_memo(f, deps)
218-
quote
219-
ref = @use_ref(nothing)
220-
if @use_did_deps_change($(esc(deps)))
221-
ref[] = $(esc(f))()
222-
end
223-
ref[]
224-
end
225-
end
315+
# ╔═╡ 3f632c14-5f25-4426-8bff-fd315db55db5
316+
export @use_ref, @use_state, @use_memo, @use_effect, @use_deps
226317

227318
# ╔═╡ c461f6da-a252-4cb4-b510-a4df5ab85065
228319
"""
@@ -238,6 +329,13 @@ After that it will.
238329
3. `deps=[something_else...]` will return true when the deps are different than they were before
239330
"""
240331
macro use_did_deps_change(deps)
332+
if !is_inside_pluto(__module__)
333+
return quote
334+
$(esc(deps))
335+
true # Simulates the first run
336+
end
337+
end
338+
241339
# Can't use @use_ref because this is used by @use_ref
242340
initialized_ref = Ref(false)
243341
last_deps_ref = Ref{Any}(nothing)
@@ -278,61 +376,6 @@ macro use_did_deps_change(deps)
278376
end
279377
end
280378

281-
# ╔═╡ 0f632b57-ea01-482b-b93e-d69f962a6d92
282-
md"""
283-
## Not really hooks but internally very hook-ish
284-
285-
These are all for making sure you have some level of Pluto-ness active. These are made to work outside of Pluto as well, but obviously give you the opposite results :P
286-
"""
287-
288-
# ╔═╡ 8c2e9cad-eb63-4af5-8b52-629e8d3439bd
289-
"""
290-
is_running_in_pluto_process()
291-
292-
This doesn't mean we're in a Pluto cell, e.g. can use @bind and hooks goodies.
293-
It only means PlutoRunner is available (and at a version that technically supports hooks)
294-
"""
295-
function is_running_in_pluto_process()
296-
isdefined(Main, :PlutoRunner) &&
297-
# Also making sure my favorite goodies are present
298-
isdefined(Main.PlutoRunner, :GiveMeCellID) &&
299-
isdefined(Main.PlutoRunner, :GiveMeRerunCellFunction) &&
300-
isdefined(Main.PlutoRunner, :GiveMeRegisterCleanupFunction)
301-
end
302-
303-
# ╔═╡ cd048a16-37f5-455e-8b6a-c098d5f83b96
304-
"""
305-
@use_deps(deps::Vector) do
306-
# ... others hooks ...
307-
end
308-
309-
Experimental function to wrap a bunch of macros in a fake cell that fully refreshes when the deps provided change. This is useful if you make a macro that wraps a bunch of Pluto Hooks, and you just want to refresh the whole block when something changes. This also clears [`@use_ref`](@ref)'s and [`@use_state`](@ref)'s, even though these don't even have a deps argument.
310-
311-
Not entirely sure how much this is necessary (or if I'm missing something obvious that doesn't make it necessary).
312-
313-
Also, this name does **not** spark joy.
314-
"""
315-
macro use_deps(fn_expr, deps)
316-
# It's not pretty, but I don't want the macroexpansion to crash already.
317-
# So I need this check before everything that uses `PlutoRunner`
318-
if !is_running_in_pluto_process()
319-
return :(throw(NotRunningInPlutoCellException()))
320-
end
321-
322-
cell_id_ref = Ref{UUID}(uuid4())
323-
324-
quote
325-
if @use_did_deps_change($(esc(deps)))
326-
$cell_id_ref[] = uuid4()
327-
end
328-
329-
with_cell_id($(esc(fn_expr)), $cell_id_ref[])
330-
end
331-
end
332-
333-
# ╔═╡ 3f632c14-5f25-4426-8bff-fd315db55db5
334-
export @use_ref, @use_state, @use_memo, @use_effect, @use_deps
335-
336379
# ╔═╡ 84736507-7ea9-4b4b-9b70-b1e9b4b33cde
337380
md"""
338381
### Until I get the PlutoTest PR out
@@ -346,9 +389,6 @@ These are, I hope, the only parts that need to explicitly reference PlutoRunner.
346389
Each of these inserts a reference to a special PlutoRunner object into the resulting expression, and that special object will be caught by PlutoRunner while evaluating the cell, and replaced with the actual value.
347390
348391
It seems a bit over-engineered, and I guess it is, BUT, this makes it possible to have a very strict sense of what cell is actually running what function. Also it allows other macros (specifically [`@use_deps`](@ref)) to insert it's own values instead of Plutos, thus kinda creating a cell-in-a-cell 😏
349-
350-
Not yet sure how these should react when they are called outside of Pluto...
351-
So... Uhhh..., they throw an error now!
352392
"""
353393

354394
# ╔═╡ 405fb702-cf4a-4d34-b8ed-d3258a61256b
@@ -695,6 +735,7 @@ uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
695735
# ╟─cce13aec-7cf0-450c-bc93-bcc4e2a70dfe
696736
# ╟─ec74d9b7-b2ff-4758-a305-c3f30509a786
697737
# ╟─8c2e9cad-eb63-4af5-8b52-629e8d3439bd
738+
# ╟─df0645b5-094a-45b9-b72a-ab7ef9901fa1
698739
# ╟─84736507-7ea9-4b4b-9b70-b1e9b4b33cde
699740
# ╟─014d0172-3425-4429-b8d6-1d195bc60a66
700741
# ╟─71963fa5-82f0-4c8d-9368-0d6ba317f59e

0 commit comments

Comments
 (0)