Tables and errors

Hello, all!

Trying to create a table that will look up some information based on a song title that the player enters. I have tried this multiple ways, and get different runtime errors:

First, Run-time error P39: invalid snippet use


check selecting:
	if noun is not a song, say "I don't understand which song you want to play." instead;
	otherwise:
		let songname be indexed text;
		let songname be the topic understood;
		continue the action.
		
carry out selecting:
	choose row with title of songname in the Table of Radio Songs;
	now songartist is the artist entry;
	now songalbum is the album entry;
	now songlength is the length entry.

Table of Radio Songs
Title	Artist	Album	Length	Absolute Length
"Rhapsody in Blue"	"George Gershwin"	"Gershwin Play Gershwin"	"14:22"	14

Next, runtime error P21:Attempt to look up non-existent row



check selecting:
	if noun is not a song, say "I don't understand which song you want to play." instead;
	otherwise:
		let songname be noun;
		continue the action.
		
carry out selecting:
	choose row with title of songname in the Table of Radio Songs;
	now songartist is the artist entry;
	now songalbum is the album entry;
	now songlength is the length entry.

Table of Radio Songs
Title	Artist	Album	Length	Absolute Length
"Rhapsody in Blue"	"George Gershwin"	"Gershwin Play Gershwin"	"14:22"	14

All support is appreciated!

How have you implemented the selecting action and songs? In the second example, the rules are written as though songs are a thing, and selecting is an action that applies to songs. But your table is set up so that the title column contains text–quoted strings.

In the first example, you’ve defined songname as a local variable in the ‘check selecting’ rule (that’s what “Let songname be…” does), which means that by the end of the rule (in fact, by the end of the “otherwise” block where it’s defined) Inform has forgotten about it. So you can’t successfully cite it in the Carry Out Selecting rule.

I’m not sure that this is it, but in either case it’d be good to post more of your code.

Yes, I have done both, sorry I was trying to keep it less confusing:



songname is text that varies.  songname is "Nothing".
songartist is text that varies.  songartist is "Nothing".
songalbum is text that varies.  songalbum is "Nothing".
songlength is text that varies.  songlength is "Nothing"

selecting is an action applying to one thing.  Understand "Select [something]" as selecting.

a song is a kind of thing. a song is usually undescribed.  a song is usually fixed in place.

rhapsody in blue is a song in DJ_Booth.
cherry blossom clinic is a song in DJ_Booth.

The problem, as Matt says, is that you’re conflating things and topics.

Here’s something that I worked up as a starting point. See the comments for a couple issues.

Music Room is a room. "This is the music room. A door leads south."

Quiet Room is south of Music Room. "This is the quiet room. A door leads north."

A jukebox is a fixed in place thing in Music Room. Understand "juke" or "box" as the jukebox.
The jukebox has a text called song title. The jukebox has a text called song artist. The jukebox has a text called song album. The jukebox has a text called song length. The jukebox has a number called time remaining.

To say quoted (val - sayable value):
	say "[quotation mark][val][quotation mark]".

Instead of examining the jukebox:
	say "The jukebox offers the following songs:[line break]";
	repeat through table of jukebox songs:
		say "    
[quoted title entry]
 by [artist entry][line break]";
	say "[line break]To play a song, PLAY or SELECT its complete title."
		
To decide if the jukebox is playing a song:
	if the time remaining of the jukebox is 0, decide no;
	decide yes.

Every turn when the jukebox is playing a song:
	if the location of the jukebox is the location:
		say "The jukebox [if time remaining of the jukebox > 1]is[else]finishes[end if] playing 
[quoted song title of the jukebox]
 by [song artist of the jukebox].";
	now time remaining of the jukebox is time remaining of the jukebox - 1;

Playing is an action applying to one topic.
Understand "play [text]" as playing.
Understand the command "select" as "play".

[It's not ideal to tie this action to a specific object like the jukebox. Would be better to define a music-playing device kind on which the action operates and make the jukebox an instance of it.]
Check playing when the jukebox is not in the location (this is the can't play a song without a jukebox rule):
	instead say "The jukebox isn't here."

The can't play a song without a jukebox rule is listed first in the check playing rulebook.

Check playing when the topic understood is not a topic listed in the table of jukebox songs:
	instead say "That's not an available song."
		
Check playing when the jukebox is playing a song:
	instead say "The jukebox is already playing a song."
	
Carry out playing a topic listed in the table of jukebox songs:
	now song title of the jukebox is title entry;
	now song artist of the jukebox is artist entry;
	now song album of the jukebox is album entry;
	now song length of the jukebox is length entry;
	now time remaining of the jukebox is absolute length entry;
	
To select is a verb.
Report playing:
	say "[We] [select] 
[quoted song title of the jukebox]
 by [song artist of the jukebox] on the jukebox, and it begins to play."

[It's not ideal to duplicate the song title as a topic to be understood and as a title to print out.]
Table of Jukebox Songs
Topic	Title	Artist	Album	Length	Absolute Length
"Rhapsody in Blue"	"Rhapsody in Blue"	"George Gershwin"	"Gershwin Plays Gershwin"	"14:22"	14
"Show No Mercy"	"Show No Mercy"	"Slayer"	"Show No Mercy"	"3:06"	3
"Not Unlike the Waves"	"Not Unlike the Waves"	"Agalloch"	"Ashes Against the Grain"	"9:16"	9	

Test me with "x jukebox / play iron man / play show no mercy / z / play rhapsody in blue / play rhapsody in blue / z / s / z / play asdfasdf / play not unlike the waves / n / play not unlike the waves / z / z / z / z / z / z".

Edit 1: renamed absolute length to time remaining, removed superfluous space, changed msg for topic not in table.
Edit 2: added rule to say quoted values.
Edit 3: added a second room and rules to handle absent jukebox.
Edit 4: “if the jukebox is in the location” -> “if the location of the jukebox is the location”
Edit 5: made the jukebox fixed in place and gave it synonyms.

Another point is that you should never use the same name for a global variable:

songname is text that varies.  

and a temporary variable:

let songname be indexed text; let songname be the topic understood; continue the action.

This won’t do what you expect. In this case, the code beginning “let songname be…” is creating a temporary variable called “songname,” setting it to the topic understood, and then throwing it out when the code block completes. Then the next rule cites the global variable also called “songname,” which you think you changed in the last code block–but you actually left it untouched. Gil talked about that here.

In fact, in these cases there’s no reason to use a global variable at all. Just use “the noun” when you’re talking about the noun, or “the topic understood” when you’re talking about the topic understood. There isn’t anything you need to pass from the Check rule to the Carry out rule.

Thank you for your help!

As a follow-up, why do you feel it was better to have certain traits of the jukebox (song title, etc.) instead of global variables?

If there were multiple jukeboxes in the game, each one could be playing its own song.

However, Inform allows for this to be modeled in several different ways.

If I were starting from scratch and not trying to illustrate how to deal with text in tables, I would probably make songs a kind of thing and place all of those properties in each song object. Music-playing devices might then be related to songs via relations like playing (for the current song) and offering (for all available songs).