Uri Guttman <u...@stemsystems.com> writes: > <forwarded to the list as i was emailed off list. no reason to keep > this private IMO> > > > On 05/24/2017 08:20 PM, lee wrote: >> Uri Guttman <u...@stemsystems.com> writes: >> >> >> you can get an array of hashes, where each hash is one row. >> >> learning dereferencing will do you much more good than using eval >> EXPR. references are key to deeper data structures in perl and are >> used all over the place. it is a core skill you should focus on as it >> will solve your current problem and many to come. >> Since when are there any data structures in perl? Variables are even >> virtually typeless. > > since when is a variable a data structure? :)
It is when it has a type. typedef struct { unsigned long MemTotal; unsigned long MemFree; unsigned long Buffers; } meminfo; meminfo test; meminfo foo[20]; int bar; int baz[20]; The difference between 'int' and 'meminfo' is that 'int' is pre-defined while 'meminfo' is defined by the programmer. Both are data types of which you can declare variables. The variables you declare are instances of the data structures that correspond to the type of the variable. For practical purposes, the variables 'test', 'foo[]', 'bar', 'baz[]' are all data structures. Perl doesn't have data structures, so variables in perl are not data structures. That is unfortunate. > the key is again references which still seems to confuse you. a scalar > can hold only one thing. A scalar can hold many different things, like an integer, a float, a double, a string, and at least three different types of references. You never really know what it happens to be. > a array a list of things. a multitude of scalars, so you never know what it happens to be > a hash can hold pairs of keys/values. of which you never know what they happen to be What about references to keys of hashes? > but most real world data is made of combinations > of those things. That's why you can define types for variables, which you can not in perl. > an array of hashes is like a list of records. a hash of > hashes can be keyed by names and then each subhash has data about its > name. you can't make those without references. Why would I need a reference to put a hash into an array or into a hash? Perl may need that internally, which isn't relevant to the programmer in the first place. >>> if you need help with references, this list is the place to ask. >> Why is it so awfully difficult to dereference a reference to an array >> that contains references to arrays, and why does DBI, for example, >> provide a function that returns such a reference? It involves holding >> the data in memory, so what is the supposed advantage of using cascaded >> references? > how will you organize the data without references? I put it into a database. > they are the branches in the tree of data. returning a single > reference is much more efficient than returning the whole array or > hash. that would involve copying the array/hash onto the stack and > then copying it again to a variable in the caller. that is very slow. Programming is even slower when you have to mess around with nested references, trying to figure out how to de-reference them correctly. I did spent hours with that ... > you say cascaded references. i call that a data tree. Arrays do not look like trees to me, they look like rows. > it is incredibly valuable and used all over the place. I'm avoiding it as much as I can. > as i said above most real world data is more complex than what a > single hash or array can hold. think about something like what is > needed to manage an editor or word processor. they need complex data > trees (usually in c/c++ but the same idea). so references aren't an > evil to be handled but the key to better management of data. In perl, references are evil. This is not for their technical aspects and advantages but for the lack of data structures, the typelessness of variables and the lack of decent ways to de-reference references in perl. A C compiler will tell you when you mistakenly pass a variable as an argument to a function rather than a reference to a variable. Perl tells you nothing. > any single slot in an array or hash can hold another > array or hash via a reference. that is building up data. That's building up a mess because you never know how to interpret what the array or the hash are holding :) > a phrase i use is compleity arises from layers of simplicity. a single > hash is simple, a large data tree which is made from simple hashes can > be very complex. references are how that works. How do you manage that? >> The program(mer) will want to work with the data rather than with >> cascaded references to it, and in the unlikely case cascaded references >> would be wanted, they could still be created. The references are merely >> an obstacle. > then how will you organize that data without references? think about it > for a minute. there is no good answer to that question. if you think > refs are obstacles, you have plenty to learn. data is complex so they > they complex structures. life can't live in single hashes. Like I said, I put it into a database. That allows me to work on a very simple layer with just the data I need to work with, saving me all problems with organizing the data because I can leave that to the database. Of course, I need to design the database in a suitable and reasonable way. That isn't too difficult. A reference to an array holding references to arrays holding the data is an obstacle because I need to work with the data, not with the references to it, and I'm having lots of trouble to de-reference a mess like that to finally get at the data. >> They are also inherently dangerous because it is never obvious if some >> variable is a reference to something or not, and that variables are >> virtually typeless contributes to that. Otherwise, references could be >> helpful for passing data to functions. > it is easy to tell. use the ref function. That is another obstacle. Am I seriously supposed to run tests with 'ref' against every parameter passed to every function I might write? That is something perl should do for me, just like a C compiler does. > and if you design your structures cleanly, I do not design data structures in perl. That is hardly possible when everything is typeless and when the language doesn't have any support for it. > you generally know when a value should be a ref or a regular value. Yes, but using references in perl is very awkward. I almost always pass variables, not references to functions. I know it's not ideal for performance, but it's much easier to manage. > if you have to have either type, checking with ref will > do the trick. >> For example: >> >> >> my $foo; >> >> >> Is that a reference? An integer? A float? A vector of characters? A >> data structure? A character? Something else? There is no way to >> tell. Pass it to a function and you have to ask again if it's a >> reference or a variable. > perldoc -f ref See it from the perspective of the programmer: They need to go to lengths to figure out what $foo is when looking at the code. They might have to put in a print statement to print debugging information to see what 'ref' has to say about $foo. They can even get surprised because $foo may suddenly change from an integer to a reference to an array holding references to arrays holding references to functions. That is evil. Have some mercy with the programmers, please :) > and you rarely need to know so many different types of values in one scalar. Consider the simple case of reading data provided by users, like a CSV. You may get all kinds of different numerical values or strings or undef from any field where you may expect the type of data you get, or a different type. It's similar with data from a database, as you might change a TEXT column into an INT column after a while because you found out only later that all the data being held in that column is integers. In the first case, you need to use appropriate checks to make sure you get the kind of data you're expecting. In the second case, you very likely don't need to do anything. In both cases, it suddenly becomes a tremendous advantage that variables in perl are typeless because your program will handle the data and does not require serious modifications, like a C program would. Still it is crucial what types of data is being held in your scalars because that is the very data your application does its work with. And there's the third case of the programmers either trusting or distrusting themselves (or each other), which would either require to check every variable passed to a function or otherwise somewhere appearing, or to just let it go and to assume that the variable in question will always hold data of the expected type. References make this worse, not any better. >> Why don't references at least require a different notation? An 'int >> *foo;' tells you right away what it is. >> >> >> typedef struct { >> unsigned long MemTotal; >> unsigned long MemFree; >> unsigned long Buffers; >> } meminfo; >> > so use hungarian notation in the name. $foo_ref. not what i would do but > it works for that. That's assuming never making mistakes by putting an unexpected type of data into a variable. It requires more work from the programmers. If there was a way to declare types for variables, we could make use of that and receive error messages when we made mistakes. >> ... also tells you what it is, and when you try to misuse it, you get an >> error message. It is impossible to create variables of self-defined >> types in perl because the variables don't have types to begin with. >> That includes data structures. > this is perl. it is designed to allow anything to be stored in a slot. > you said it earlier, it is not strongly typed which is a win for many > things. an array can hold different value types. Yes, it's a big advantage. It would be better if it was also possible to bind variables to types. We could even have a way to define data structures. > and in c you don't get deep structures without pointers and that has the > same issues you seem to find with references. They are so much easier to deal with in C that I like using references there. >> My limit with "data structures" in perl are strided lists. They are a >> poor clutch and I don't like them, but unfortunately, there are no data >> structures in perl. > you are wrong about no data structures in perl. you will have to take my > word on that (and everyone else who teaches perl). you just haven't > learned references yet. once you do, it will all make more sense. So how do you define data structures in perl? >>>> They are potentially dangerous because you might fetch huge numbers of >>>> rows and run into memory issues which could bring down the server. I'm >>>> avoiding them unless they have a significant advantage and when I can be >>>> sure not to fetch too many rows, or when I would have all the data in >>>> the program anyway. >>> you can get a row at a time i am sure with each row being a hash. >> The hash would have to be transformed into an array. Hashes are >> difficult to debug because you don't get any error when using elements >> that do not exist, so they are as inherently dangerous as references are >> --- or even more dangerous because you sometimes get error messages >> telling you that something cannot be used as reference to a an array. > there are ways to lock hash keys so look for that. i have yet to need > that and don't run into that problem much. Lock them? Like you would get an error message when trying to use a key that doesn't exist? I'd find that very useful because it happens often enough. > it all comes down to experience in anything like this. Experience is always important. My perspective with perl is quite a bit limited to database applications. > you haven't used references enough to really get them so they seem > nasty to you. i can only say you need to persevere with them. you are > welcome to show code that bothers you and ask questions here. but > ranting on how references are evil is not productive anywhere. Look at the selectall_arrayref() provided by DBI[1]. How do you de-reference nested references to things? It doesn't work to just stack up the operators as deep as the nesting goes. It is difficult to ask a specific question when you don't really know what you need to ask because you will only know that once you found some answers. Let's say you have a table in a database and your query returns 100 rows with 10 fields in each row. You use selectall_arrayref() to get the result of the query. How do you get the content of row 25, field 5? I guess you understand how I consider references as an obstacle with a question like that. I wouldn't even use selectall_arrayref() if selectall_array() was available as documented, which it is not. [1]: http://search.cpan.org/~timb/DBI-1.636/DBI.pm#selectall_arrayref -- "Didn't work" is an error. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/