http://www.perlmonks.org?node_id=997682

perl-diddler has asked for the wisdom of the Perl Monks concerning the following question:

I must never have tried this before, I tried using keys on a hash I'd just blessed, only to be told that keys can't be used on a blessed object:
Type of argument to keys on reference must be unblessed hashref or arr +ayref at ...
How do I print the keys? I feel like I'm missing some obvious step?

Replies are listed 'Best First'.
Re: How do you find keys of a Blessed Hash?
by moritz (Cardinal) on Oct 07, 2012 at 14:51 UTC
      You're right... hmmm... works in simple case, ARG, but not where I'm using it... ooooo Might have something to do with my using Alias in the code .... gonna have to go ponder this some more...I thought it seemed to strange that keys didn't work -- thanks for the reality check!

        perl-diddler:

        Assuming Corion located the problem for you, then you need only dereference the hash yourself, rather than relying on keys to do it for you:

        $ cat test.pl #!/usr/bin/perl *STDERR = *STDOUT; $|=1; my $hr = bless {a=>1, b=>2}, "food"; print "Manual deref: ", join(", ", keys %$hr), "\n"; print "Auto deref: ", join(", ", keys $hr), "\n"; $ perl test.pl Manual deref: a, b Type of argument to keys on reference must be unblessed hashref or arr +ayref at test.pl line 8.

        Update: Fixed formatting.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

        Instead of running off, again, on a wild goose chase, it maybe would be simpler to just read keys, the official documentation? It mentions there that:

        Starting with Perl 5.14, keys can take a scalar EXPR, which must contain a reference to an unblessed hash or array. The argument will be dereferenced automatically. This aspect of keys is considered highly experimental. The exact behaviour may change in a future version of Perl.

        ... and without seeing your code, my guess is that you are "using" that experimental feature, knowingly or not.

Re: How do you find keys of a Blessed Hash?
by Corion (Patriarch) on Oct 07, 2012 at 15:03 UTC

    The obvious step would be to show the relevant part of your code. Also see References Quick Reference, and maybe the relevant parts of Learning Perl. Amazon tells me that "reference" is mentioned on page 49 of "Learning Perl".

      I've all but given up on trying to show parts of my code ... most of my code is tied in with library functions and problems I find are never in simple 1 liners, but buried amongst 2000 other lines of code. Trying to reproduce it in a short example invariably removes the ability to reproduce the bug.

      I've submitted programs that caused the perl compiler to dump core. They were closed out because they were too difficult for the developers to figure out. Note: all of my programs were written in pure perl. It shouldn't be possible for them to cause perl to core dump, any more than it should be possible for a normal user program to cause the OS kernel to panic and blue-screen(or dump core)...

      Nevertheless, even though clearly a bug was demonstrated that if perl was an OS would be defined as a Denial of Service, such bugs are routinely ignored as it's assumed the user has done something strange -- ignoring the fact that nothing the user in pure perl as a normal user should be able to corrupt the interpreter to the point it dumps core.

      I'm more than happy to share code... AND have done so in the past. But I didn't sufficiently deconstruct my program into an artificial and thereby, unrelated test case and got chastised for it by 'you'...#985099.

      So it sorta puts me off wanting to share code when I get caustic replies for not doing it in the way someone finds acceptable. You have to understand, I listen to your feedback. If you want me to share more code, you'd have to stop chastising me for the code I submit. I know it's demanding of me, but your tone was spiteful and you even got several votes indicating your spiteful tone to put me down was appreciated. That doesn't come off as a very friendly helping community IMO...but I know my opinion doesn't count for much.

        I upvoted you on the level 2 reply to Corion for having the honesty to express your frustration and because it triggered a superb answer by Corion.

        I want to stress and double stress the truth of what Corion is saying: stripping down your code to the smallest bit is time consuming work, but it is still ESSENTIAL. If you have truly found a bug in Perl, then the maintainers need to know the smallest set of circumstances that cause it. This helps them quickly identify where in the Perl codebase the code relevant to creating the bug lives.

        Stripping down code without disrupting a bug is an artform and sometimes requires great skill. In a way it is catch-22 for "young" (professionally speaking) Perl coders : if you had the skill and understanding of codeflow and syntax to do the stripping down you might not need help figuring out the bug in the first place.

        Sometimes the good monks here can address that issue by asking people to post code, but that only works if they are doing small programs with few outside influences. Even if a newbee can't see where the codeflow or data initialization has gone wrong, a more experienced eye can. That's why we ask people to post code.

        But as you point out, this is not the situation for you. Your programs aren't small and they have lots of outside influences (third party libraries). This leaves us with two possibilities: (a) you can strip it down and won't take the time (b) you are trying to write code that outstrips your mastery of Perl.

        As a general rule, if one is writing code that is too complex for one to strip down on one's own to the smallest bit that reproduces the bug, then one is probably writing code beyond one's skill level in that particular language. Just as kids shouldn't swim beyond where they can swim back, or climb jungle gyms and trees beyond the point where they can get themselves down, one shouldn't aspire to write and design programs beyond the point one can independently strip down code to the smallest segment that reproduces the bug.

        Assuming you are a good soul and not lazy, that leaves me with the thought that perhaps you are overreaching your skill with some of the programs you are trying to write. You may be a top notch C++ coder and can do fancy algorithm dances in C++ or Algol or Ruby or whatever, but each language has its own idiom and debugging assumptions. Perhaps you might want to consider working on more simple programs in Perl until you've become more skilled at isolating and reproducing bugs in small code snippets?

        ... most of my code is tied in with library functions and problems I find are never in simple 1 liners, but buried amongst 2000 other lines of code. Trying to reproduce it in a short example invariably removes the ability to reproduce the bug.

        That is the point of debugging your code. By reducing your code to a small snippet, you stepwise eliminate all unrelated parts. And usually, if the symptom goes away between two editions of your program, it is highly likely that the part you changed last is related to the symptom. So the trick is to keep removing parts without changing the symptom until only the core code related to the symptom is left over or until it becomes clear to you what the cause was.

        If this sounds like work, that is because it is. This is why you need to do the work of removing all the unrelated cruft from your code, instead of feeling entitled that others wade through your code.

        I've submitted programs that caused the perl compiler to dump core. They were closed out because they were too difficult for the developers to figure out. Note: all of my programs were written in pure perl. It shouldn't be possible for them to cause perl to core dump, any more than it should be possible for a normal user program to cause the OS kernel to panic and blue-screen(or dump core)...

        Nevertheless, even though clearly a bug was demonstrated...

        No. All I've seen from you were programs that could not run on their own because they relied on various other libraries. You demonstrated enough lack of grasp on your environment that it is highly likely that you mixed up compiler versions and Perl versions. Doing so is advised against and will lead to core dumps. Claiming that you have "clearly demonstrated" when you just tell vague tales of an environment that you yourself messed up is misleading.

        I'm more than happy to share code... AND have done so in the past. But I didn't sufficiently deconstruct my program into an artificial and thereby, unrelated test case and got chastised for it by 'you'...#985099.

        I think you shouldn't feel "chastised". I mean Re^6: Why isn't a fatal error trappable? as solid advice from experience. Debugging a program is not like retelling an epic tale from memory where the minutiae don't matter. Debugging is assiduously going over the program and its output with a fine comb, for as long as it takes. We don't know about your environment and your library versions etc., but for debugging, reproducing your environment is necessary. If you make it difficult for us to reproduce your situation, you are making it difficult for yourself to get help.

        I know it's demanding of me, but your tone was spiteful and you even got several votes indicating your spiteful tone to put me down was appreciated. That doesn't come off as a very friendly helping community IMO...but I know my opinion doesn't count for much.

        Seriously, I'm not doing this to be "unfriendly". I'm doing this to get results, to get programs debugged. And the only way I know to debug programs together with other people is to enable people to reproduce the situation. I give you that advice to enable others to help you. If this comes across as "unfriendly" to you, and if you feel that you need more hand-holding, then "listening" to the feedback is not enough. You will have to start doing work yourself, as has been outlined several times already - by reducing your problem to a small, self-contained program that exhibits the problem.