Need help with lua_missions

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
winded
Prole
Posts: 5
Joined: Wed Sep 17, 2014 7:51 pm

Need help with lua_missions

Post by winded »

Hi everyone!

So first a disclaimer - I'm super new to coding. Lua is the first language I've ever tried to learn. However, a lot of the tutorials and posts that you guys have on the forum have been super helpful - especially the ones from Kikito.

I just recently finished *almost* all of the lua_missions that he has up in Github, and I have a few questions about them:

1. I don't know any regular expressions, so I skipped the second half of patterns.lua. Is there a good place to learn them? Do I need to know them right away, or should I just wait and learn them if I need? What are they used for?
2. I'm really thrown by metatables. In particular, I don't understand why in lines 66 and 75 of indices.lua, t2.x returns nil. It was just set to equal 1. That makes it seem like tables that have been associated with metatables can't be directly altered. Is that only the case when you're using the __newindex metamethod? Why?
3. I'm completely lost on exercise.lua. First, I don't understand why we're trying to use a metamethod on strings instead of tables, when the previous lesson was all about using them on tables. Do they work on strings? How do you set them up to work with strings? Second, it seems like you should be able to solve this with a simple function. For the first set, why wouldn't you just use this sort of thing:

Code: Select all

local function starts_with(input_string, snippet)
  return input_string:sub(1, #snippet) == snippet
end
The ends_with function would be really similar, just using #input_string to count backwards. These don't actually work, so I assume I'm approaching it wrong, since the hint is to use a metatable. Again, I'm sorry if these questions are silly. I'm learning a TON, but I'm clearly still very much a beginner. :)

Thanks!

PS - @Mods - I'm not sure if this is the right place to post about this, but it's where Kikito posted when he announced lua_missions, so I figured it was a good place to start. Also you people seem very friendly!
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: Need help with lua_missions

Post by Inny »

winded wrote:Hi everyone!

So first a disclaimer - I'm super new to coding. Lua is the first language I've ever tried to learn. However, a lot of the tutorials and posts that you guys have on the forum have been super helpful - especially the ones from Kikito.
Hi! Totally glad you've decided to learn programming and chose Lua to start.
winded wrote:I just recently finished *almost* all of the lua_missions that he has up in Github, and I have a few questions about them:

1. I don't know any regular expressions, so I skipped the second half of patterns.lua. Is there a good place to learn them? Do I need to know them right away, or should I just wait and learn them if I need? What are they used for?
Regular expressions are complex to people new to the concept, and then a very easy tool for people who understand them. You may want to return to them later if they're proving to be difficult. You can still go very far without them. But I'd advise to still try to learn them, as they're very handy.

What regular expressions, and Lua's patterns, are good for is looking at a string that is decidedly "regular" and pull out regular pieces of it. Like, as a for instance, these sentences are regular. They contain words separated by spaces and punctuation marks. Now, here are some messages that aren't like my sentences:
Oct 17 08:59:00 suod newsyslog[6215]: logfile turned over
Oct 17 08:59:04 cdr.cs.colorado.edu amd[29648]: noconn option exists, and was turned on! (May cause NFS hangs on some systems...)
Oct 17 08:59:09 freestuff.cs.colorado.edu ftpd[4502]: FTP ACCESS REFUSED (anonymous password not rfc822) from sdn-ar-001nmalbuP302.dialsprint.net [168.191.180.168]
Oct 17 08:59:24 peradam.cs.colorado.edu sendmail[21601]: e9HExOW21601: SYSERR(root): Can't create transcript file ./xfe9HExOW21601: Permission denied
With regular expressions, a program could tell the difference between my sentences and syslog messages, and pull out useful pieces.
winded wrote:2. I'm really thrown by metatables. In particular, I don't understand why in lines 66 and 75 of indices.lua, t2.x returns nil. It was just set to equal 1. That makes it seem like tables that have been associated with metatables can't be directly altered. Is that only the case when you're using the __newindex metamethod? Why?
__newindex means "There is a new index in the table", and that lets you do something with the value instead of the default action. It's not that putting a metatable on another table does that automatically, it's that the metatable will let you set a __newindex which will define it. In that mission, Kikito is trying to show you that the __newindex function is saying that trying to set something on t2 will instead put it on t1. But a different __newindex function could do something entirely different.
winded wrote:3. I'm completely lost on exercise.lua. First, I don't understand why we're trying to use a metamethod on strings instead of tables, when the previous lesson was all about using them on tables. Do they work on strings? How do you set them up to work with strings? Second, it seems like you should be able to solve this with a simple function. For the first set, why wouldn't you just use this sort of thing:

Code: Select all

local function starts_with(input_string, snippet)
  return input_string:sub(1, #snippet) == snippet
end
The ends_with function would be really similar, just using #input_string to count backwards. These don't actually work, so I assume I'm approaching it wrong, since the hint is to use a metatable.
So this one is a bit more subtle. You can set any metatable on any table, but only per. One table can't really have two metatables, not without some kind of trickery with __index and __newindex. But, every table can have a different metatable. string, and some of the other simple types, can also have a metatable, EXCEPT that all strings must have the same metatable. You can't have two strings with different metatables. You can change which metatable it is with debug.setmetatable, but I'd advise against it. It's not a very useful thing to do. The default metatable for strings has already been set, and it has the most important metamethod set already (__index, pointing at the string library). In that exercize, kikito is showing you that by changing the string library table, all strings will have this new method on them.

Though, I agree with you that the simple function is the better way to go. And, actually kikito would agree with you that the simple function is better, as changing the default library tables isn't a very friendly thing to do. It could cause strange behavior in any code you may be using from other sources.
winded wrote:Again, I'm sorry if these questions are silly. I'm learning a TON, but I'm clearly still very much a beginner. :)

Thanks!
They're not silly at all, and you've done the most important thing that people new to programming can do, which is to ask when you have questions. Good luck!
winded
Prole
Posts: 5
Joined: Wed Sep 17, 2014 7:51 pm

Re: Need help with lua_missions

Post by winded »

Thanks so much Inny! This was very helpful.
But I'd advise to still try to learn them, as they're very handy.
With your encouragement I went back and pulled the up the Wikipedia page for Regex and went through the lessons. It's not nearly as scary as it seemed at first!
In that mission, Kikito is trying to show you that the __newindex function is saying that trying to set something on t2 will instead put it on t1.
I think I get the idea here, but I'm still a bit confused about the implementation in this case. The way it was setup was:

Code: Select all

local t2 = setmetatable({}, {
  __newindex = function(t, key, value)
    t1[key] = value * 10
  end
})
t2.x = 1
So it sounds like what you're saying is that since we're using __newindex, you'd have to define that metamethod as having both:

Code: Select all

t1[key] = value * 10
t2[key] = value
because otherwise it'll only be set in t1. Is that correct? It just seems strange to me because I don't think most other metamethods are like that, right?
Though, I agree with you that the simple function is the better way to go.
I'm glad to hear I'm not crazy for thinking this seemed more complicated than necessary! Although I do understand the point about learning the tools in the right way based on simple cases. And actually this seems really helpful! I found this page, which helped a lot:
http://lua-users.org/lists/lua-l/2005-08/msg00543.html
I didn't realize that you could just put stuff into and out of the default function tables at will, so I just put that function into the string table and it all worked.
All missions are complete now. Thanks a ton for the help!
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Need help with lua_missions

Post by s-ol »

winded wrote:Thanks so much Inny! This was very helpful.

Code: Select all

local t2 = setmetatable({}, {
  __newindex = function(t, key, value)
    t1[key] = value * 10
  end
})
t2.x = 1
So it sounds like what you're saying is that since we're using __newindex, you'd have to define that metamethod as having both:

Code: Select all

t1[key] = value * 10
t2[key] = value
because otherwise it'll only be set in t1. Is that correct? It just seems strange to me because I don't think most other metamethods are like that, right?
No, the new way t2 works is only modifying t1.
Not all metamethods work like that in that they do not first do the normal behaviour but they all change the default behaviour somehow. If you write

Code: Select all

setmetatable(t1, { __newindex = function () end })
setmetatable(t2, { __newindex = function (t, k, v)
    rawset(t, k, v) -- rawset so we don't get back into this metamethod
  end } )
After this, you can no longer add new entries to t1 (except with rawset). t2 behaves exactly as it would have without a metamethod.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests