mikecargal

mikecargal

Hands-on Rust: question about get_component

Title: Hands-on Rust: question about get_component (page 295)

(feel free to respond. “You dug you’re own hole… good luck”)

I have something wrong implementing the “adventurer isn’t an Octopus” code. (Pretty sure it’s “wrong” somewhere else in my code, since I checked and rechecked this specific code several times, but I’m trying to sort out what I may have wrong)

In trying to track down what I’ve done wrong I’ve changed some of the code as follows: (mainly to break a few things out and get some visibility with ```println!()`` calls (adding line numbers to match against stack trace). (also, unfortunately, since this is panicking, it’s actually on picking up the first sword, so not exactly the scenario I’m trying to eventually fix)

40               items
41                   .iter(ecs)
42                   .filter(|(_entity, _item, &item_pos)| item_pos == player_pos)
43                   .for_each(|(entity, _item, _item_pos)| {
44                        commands.remove_component::<Point>(*entity);
45                        commands.add_component(*entity, Carried(player));
46                        if let Ok(e) = ecs.entry_ref(*entity) {
47                            println!("Entity:{:#?}", e.archetype());
48                            let is_weapon = e.get_component::<Weapon>().is_ok();
49                            println!("Entity is weapon: {}", is_weapon);
50                            <(Entity, &Carried, &Weapon)>::query()
51                                .iter(ecs)
52                                .filter(|(_, c, _)| {
53                                    let is_carried_by_player = c.0 == player;
54                                    println!(
55                                        "carried by player: {} {}",
56                                        is_carried_by_player, is_weapon
57                                    );
58                                    is_carried_by_player && is_weapon
59                                })
60                                .for_each(|(e, _, _)| {
61                                    println!("Remove Weapon Entity");
62                                    commands.remove(*e)
63                                })

For which, I get the following console output:

Entity:Archetype {
    index: ArchetypeIndex(
        10,
    ),
    entities: [
        Entity(
            25,
        ),
        Entity(
            24,
        ),
        Entity(
            22,
        ),
        Entity(
            47,
        ),
        Entity(
            46,
        ),
        Entity(
            45,
        ),
        Entity(
            44,
        ),
        Entity(
            40,
        ),
        Entity(
            35,
        ),
        Entity(
            33,
        ),
        Entity(
            59,
        ),
        Entity(
            58,
        ),
        Entity(
            54,
        ),
        Entity(
            48,
        ),
        Entity(
            79,
        ),
        Entity(
            76,
        ),
    ],
    layout: EntityLayout {
        components: [
            ComponentTypeId {
                type_id: TypeId {
                    t: 9061793563588654225,
                },
                name: "bracket_geometry::point::Point",
            },
            ComponentTypeId {
                type_id: TypeId {
                    t: 8331237624739738968,
                },
                name: "dungeoncrawl::components::Render",
            },
            ComponentTypeId {
                type_id: TypeId {
                    t: 18175530127838128523,
                },
                name: "dungeoncrawl::components::Name",
            },
            ComponentTypeId {
                type_id: TypeId {
                    t: 14425425821466115813,
                },
                name: "dungeoncrawl::components::Item",
            },
            ComponentTypeId {
                type_id: TypeId {
                    t: 1855713956641428298,
                },
                name: "dungeoncrawl::components::Damage",
            },
            ComponentTypeId {
                type_id: TypeId {
                    t: 2499425021939920047,
                },
                name: "dungeoncrawl::components::Weapon",
            },
        ],
        component_constructors: [
            0x0000000100f9f170,
            0x0000000100f9fb50,
            0x0000000100fa0200,
            0x0000000100f9f2e0,
            0x0000000100f9fcd0,
            0x0000000100f9f260,
        ],
    },
    subscribers: Subscribers {
        len: 0,
    },
}
Entity is weapon: false
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: AccessDenied', /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/query/mod.rs:340:65
stack backtrace:
   0: rust_begin_unwind
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:495:5
   1: core::panicking::panic_fmt
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/panicking.rs:92:14
   2: core::option::expect_none_failed
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/option.rs:1268:5
   3: core::result::Result<T,E>::unwrap
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:973:23
   4: legion::internals::query::Query<V,F>::iter_chunks_unchecked
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/query/mod.rs:340:24
   5: legion::internals::query::Query<V,F>::iter_unchecked
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/query/mod.rs:484:9
   6: legion::internals::query::Query<V,F>::iter
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/query/mod.rs:538:18
   7: dungeoncrawl::systems::player_input::player_input::{{closure}}
             at ./src/systems/player_input.rs:50:29
   8: core::iter::traits::iterator::Iterator::for_each::call::{{closure}}
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:675:29
   9: core::iter::adapters::filter_fold::{{closure}}
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:1071:44
  10: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:269:13
  11: core::iter::traits::iterator::Iterator::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2023:21
  12: <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::fold::flatten::{{closure}}
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/flatten.rs:332:30
  13: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:269:13
  14: core::iter::adapters::map_fold::{{closure}}
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:905:21
  15: core::iter::traits::iterator::Iterator::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2023:21
  16: <core::iter::adapters::fuse::Fuse<I> as core::iter::adapters::fuse::FuseImpl<I>>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/fuse.rs:315:19
  17: <core::iter::adapters::fuse::Fuse<I> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/fuse.rs:106:9
  18: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:945:9
  19: <core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/chain.rs:123:19
  20: <core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/chain.rs:120:19
  21: <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/flatten.rs:335:9
  22: <core::iter::adapters::flatten::Flatten<I> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/flatten.rs:193:9
  23: <core::iter::adapters::Filter<I,P> as core::iter::traits::iterator::Iterator>::fold
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:1135:9
  24: core::iter::traits::iterator::Iterator::for_each
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:678:9
  25: dungeoncrawl::systems::player_input::player_input
             at ./src/systems/player_input.rs:40:17
  26: dungeoncrawl::systems::player_input::player_input_system::{{closure}}
             at ./src/systems/player_input.rs:10:1
  27: <F as legion::internals::systems::system::SystemFn<R,Q>>::run
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/system.rs:220:9
  28: <legion::internals::systems::system::System<R,Q,F> as legion::internals::systems::schedule::Runnable>::run_unsafe
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/system.rs:191:9
  29: legion::internals::systems::schedule::Executor::run_recursive
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/schedule.rs:384:9
  30: legion::internals::systems::schedule::Executor::run_systems::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/schedule.rs:353:34
  31: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/for_each.rs:47:9
  32: <rayon::iter::filter::FilterFolder<C,P> as rayon::iter::plumbing::Folder<T>>::consume
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/filter.rs:123:24
  33: rayon::iter::plumbing::Folder::consume_iter
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:179:20
  34: rayon::iter::plumbing::Producer::fold_with
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:110:9
  35: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:438:13
  36: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:418:21
  37: rayon_core::join::join_context::call_a::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:124:17
  38: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:322:9
  39: std::panicking::try::do_call
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:381:40
  40: ___rust_try
  41: std::panicking::try
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:345:19
  42: std::panic::catch_unwind
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:396:14
  43: rayon_core::unwind::halt_unwinding
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/unwind.rs:17:5
  44: rayon_core::join::join_context::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:141:24
  45: rayon_core::registry::in_worker
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:879:13
  46: rayon_core::join::join_context
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:132:5
  47: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:416:47
  48: rayon::iter::plumbing::bridge_producer_consumer
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:397:12
  49: <rayon::iter::plumbing::bridge::Callback<C> as rayon::iter::plumbing::ProducerCallback<I>>::callback
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:373:13
  50: <rayon::range::Iter<usize> as rayon::iter::IndexedParallelIterator>::with_producer
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/range.rs:112:17
  51: rayon::iter::plumbing::bridge
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/plumbing/mod.rs:357:12
  52: <rayon::range::Iter<usize> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/range.rs:88:17
  53: <rayon::iter::filter::Filter<I,P> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/filter.rs:46:9
  54: rayon::iter::for_each::for_each
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/for_each.rs:12:5
  55: rayon::iter::ParallelIterator::for_each
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.5.0/src/iter/mod.rs:369:9
  56: legion::internals::systems::schedule::Executor::run_systems
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/schedule.rs:347:17
  57: legion::internals::systems::schedule::Schedule::execute::{{closure}}::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.3.1/src/internals/systems/schedule.rs:518:28
  58: rayon_core::join::join::call::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:102:18
  59: rayon_core::join::join_context::call_a::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:124:17
  60: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:322:9
  61: std::panicking::try::do_call
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:381:40
  62: ___rust_try
  63: std::panicking::try
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:345:19
  64: std::panic::catch_unwind
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:396:14
  65: rayon_core::unwind::halt_unwinding
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/unwind.rs:17:5
  66: rayon_core::join::join_context::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/join/mod.rs:141:24
  67: rayon_core::registry::Registry::in_worker_cold::{{closure}}::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:469:21
  68: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::call::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/job.rs:113:21
  69: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:322:9
  70: std::panicking::try::do_call
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:381:40
  71: ___rust_try
  72: std::panicking::try
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:345:19
  73: std::panic::catch_unwind
             at /Users/mike/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:396:14
  74: rayon_core::unwind::halt_unwinding
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/unwind.rs:17:5
  75: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/job.rs:119:38
  76: rayon_core::job::JobRef::execute
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/job.rs:59:9
  77: rayon_core::registry::WorkerThread::execute
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:753:9
  78: rayon_core::registry::WorkerThread::wait_until_cold
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:730:17
  79: rayon_core::registry::WorkerThread::wait_until
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:704:13
  80: rayon_core::registry::main_loop
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:837:5
  81: rayon_core::registry::ThreadBuilder::run
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:56:18
  82: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}
             at /Users/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.0/src/registry.rs:101:20
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

So my questions are

1 - Am I completely misunderstanding what the archetype() function returns? It looks to me, like it says that the entity DOES have a Weapon component. However the e.get_component::<Weapon>().is_ok() call returns false

2 - Why am I getting an access denied panic (beyond the immediate "because you tried to unwrap() an Err (stupid)?
Item 7 on the stack trace points to my code, but it’s the <(Entity, &Carried, &Weapon)>::query() line and I’m not sure what about that could trigger a panic.

1 1158 5

Marked As Solved

herbert

herbert

Author of Hands-on Rust

Glad that fixed it! I’ll add the read_component to the instructions in the next build. Thanks. :slight_smile:

Popular Prag Prog topics Top

johnp
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’. In particula...
5 3523 1
New
yulkin
your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
1 4033 2
New
sdmoralesma
Title: Web Development with Clojure, Third Edition - migrations/create not working: p159 When I execute the command: user=&gt; (create-...
5 1082 2
New
herminiotorres
Hi @Margaret , On page VII the book tells us the example and snippets will be all using Elixir version 1.11 But on page 3 almost the en...
15 1541 13
New
herminiotorres
Hi! I know not the intentions behind this narrative when called, on page XI: mount() |&gt; handle_event() |&gt; render() but the correc...
3 1296 17
New
AufHe
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113. Iteration A1 - Seeing the list of prod...
0 2609 9
New
taguniversalmachine
It seems the second code snippet is missing the code to set the current_user: current_user: Accounts.get_user_by_session_token(session["...
0 1878 8
New
Henrai
Hi, I’m working on the Chapter 8 of the book. After I add add the point_offset, I’m still able to see acne: In the image above, I re...
1 1014 4
New
jwandekoken
Book: Programming Phoenix LiveView, page 142 (157/378), file lib/pento_web/live/product_live/form_component.ex, in the function below: d...
7 1151 10
New
a.zampa
@mfazio23 I’m following the indications of the book and arriver ad chapter 10, but the app cannot be compiled due to an error in the Bas...
1 3322 6
New

Other popular topics Top

DevotionGeo
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
7 6656 2
New
New
PragmaticBookshelf
A Hero’s Journey with Chris Pine @chrispine Chris Pine, author of Learn to Program, Third Edition, discusses his journey to beco...
81 3229 26
New
rustkas
Intensively researching Erlang books and additional resources on it, I have found that the topic of using Regular Expressions is either c...
91 4884 44
New
AstonJ
Was just curious to see if any were around, found this one: I got 51/100: Not sure if it was meant to buy I am sure at times the b...
4 3432 2
New
PragmaticBookshelf
Author Spotlight Jamis Buck @jamis This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
21 5361 10
New
PragmaticBookshelf
Author Spotlight Mike Riley @mriley This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
62 6126 20
New
PragmaticBookshelf
Author Spotlight Rebecca Skinner @RebeccaSkinner Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
106 10214 29
New
PragmaticBookshelf
Author Spotlight: Karl Stolley @karlstolley Logic! Rhetoric! Prag! Wow, what a combination. In this spotlight, we sit down with Karl ...
31 3516 17
New
CommunityNews
A Brief Review of the Minisforum V3 AMD Tablet. Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
0 1247 0
New

Latest in PragProg

View all threads ❯