Just a few things to throw out here:
-> Still wondering about the Squeakland image; the download is less than 1MB, so obviously it's not in there (right?).
-> When you're developing classes and testing stuff out, do you expose all the instance variables? And then later, remove the accessors you don't want the user to have? I notice that to test/debug it's often easiest to have access to everything from the Workspace, but really don't want that to be exposed to clients of the class.
-> If you were creating a deck (of cards) class and a card class, would you put the card's rank and suit in as strings or as symbols, keeping in mind that you were later going to reveal the class to students for educational purposes? I know I want the deck to be card neutral, i.e., to be usable for a deck of any sort of cards, but the cards themselves (for standard decks), for convenience, are described as being (rank) "King" and (suit) "Hearts". But perhaps that should be #king and #hearts. (I tend to worry about making global symbols: seems like courting trouble.)
Nothing real urgent, just stuff that has occurred to me.
On 9/8/05, Blake blake@kingdomrpg.com wrote:
-> Still wondering about the Squeakland image; the download is less than 1MB, so obviously it's not in there (right?).
Still wondering about what you're asking; the sentence is only two lines long, so obviously there's no question in there (right?).
:-)
-> When you're developing classes and testing stuff out, do you expose all the instance variables? And then later, remove the accessors you don't want the user to have?
Nope. But unless I have a reason to hide them, I have accessors for all instance variables, as a rule.
I notice that to test/debug it's often easiest to have access to everything from the Workspace, but really don't want that to be exposed to clients of the class.
You have access to everything in an Inspector, too, so you don't need to make an accessor merely for development.
-> If you were creating a deck (of cards) class and a card class, would you put the card's rank and suit in as strings or as symbols, keeping in mind that you were later going to reveal the class to students for educational purposes? I know I want the deck to be card neutral, i.e., to be usable for a deck of any sort of cards, but the cards themselves (for standard decks), for convenience, are described as being (rank) "King" and (suit) "Hearts". But perhaps that should be #king and #hearts. (I tend to worry about making global symbols: seems like courting trouble.)
It sounds as if you're worried about your #king being a problem if there's also a #king used in chess, say. But you can share #king just as you can share $R and 42. Global symbols are global constants, not global variables.
Hope this helps!
--Tom Phoenix
On Thu, 08 Sep 2005 19:23:53 -0700, Tom Phoenix rootbeer@redcat.com wrote:
On 9/8/05, Blake blake@kingdomrpg.com wrote:
-> Still wondering about the Squeakland image; the download is less than 1MB, so obviously it's not in there (right?).
Still wondering about what you're asking; the sentence is only two lines long, so obviously there's no question in there (right?).
:-)
I posted previously on downloading the Squeak plug-in and not getting an image with it. The point was made that it should be all-inclusive (which I believe is true) but the file itself is only about 900K! I'm trying to figure out if the link is wrong and needs to be corrected or what.
Nope. But unless I have a reason to hide them, I have accessors for all instance variables, as a rule.
Not a strong believer in encapsulation?<s>
I notice that to test/debug it's often easiest to have access to everything from the Workspace, but really don't want that to be exposed to clients of the class.
You have access to everything in an Inspector, too, so you don't need to make an accessor merely for development.
Yeah, but if I want to test code that's in a method from the Workspace, I don't think the Inspector's going to help there.
It sounds as if you're worried about your #king being a problem if there's also a #king used in chess, say. But you can share #king just as you can share $R and 42. Global symbols are global constants, not global variables.
Yeah, I know that. It just...feels wrong.<s> I guess they have no semantic value at all, other than what's ascribed to them. Could make for some REALLY obscure bugs under some unlikely situations....
Hope this helps!
It does, thanks. I welcome any other thoughts here, too.
Here's another one: Delegation. I tend to delegate like mad--years of Delphi programming and an aversion to the notion of identification ("Whaddayamean an X is a Y? No it's not, it's an X!")--and I'm wondering if that's a bad idea for a deck of cards.
A deck of cards IS an ordered collection of cards. What I have is a deck of cards which HAS an ordered collection of cards, along with an ordered colleciton representing the as-yet undealt cards, plus an ordered collection of ordered collections for all the other piles (discard, hands, whatever is needed for the particular game). But I keep having to pass everything through to the master ordered collection.
Tim Phoenix>"Nope. But unless I have a reason to hide them, I have accessors for all instance variables, as a rule."
Blake>"Not a strong believer in encapsulation?<s>"
I'm with you, Blake. I only add accessors and/or mutators when I have a demonstrated need for them. And I don't automatically add a mutator for each acessor (or vice versa,) either.
In Smalltalk, there is no justification for "**always** using an accessor/mutator method." There are architectural and design reasons for doing that in particular cases, just as there are architectural and design reasons for not doing that in other cases. One size does not fit all.
An accessor method must be justified by one of two requirements: 1) The value of the instance variable needs to be provided as a part of the object's API, or 2) the value must be lazily initialized or recomputed. Otherwise, an accessor is not only unnecessary, it violates the information hiding principle.
A mutator method must be justified by one of two requirements: 1) The value of the instance variable must be settable as part of the object's public API, or 2) there is an invariant that must be maintained whenever the value of the instance variable is changed (e.g., a change event must be propagated, the value of another instance variable must be recomputed, etc.) Otherwise, a mutator is not only unnecessary, it violates encapuslation.
Re: Global Symbols
Blake>[Using global symbols] "Could make for some REALLY obscure bugs under some unlikely situations...."
Such as? Symbols aren't mutable. And they're flyweights. Other than that, they are subject to all the same misuses as would apply to String instances, aren't they? (Your original question did suggest using Strings as the alternative.)
Blake>"A deck of cards IS an ordered collection of cards."
Except when it's a SortedCollection of cards. Or an Array of cards. Or a linked list of cards. Or... I think you get the point.
Also, it's not necessarily the case that all the operations in the API of Collection should be supported by a deck of cards. More importantly, the level of abstraction and the semantics are both different. For one thing, a deck of cards should not contain numbers, Strings nor Timestamps. For another, there is both a semantic and a behavioral distinction between the object that represents the state of a particular deck of cards at a particular moment in a particular game and one that defines the complete set of cards with which the game is played.
--Alan
-----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev- bounces@lists.squeakfoundation.org] On Behalf Of Blake Sent: Thursday, September 08, 2005 10:03 PM To: squeak-dev@lists.squeakfoundation.org Subject: Miscellaneous questions...
Just a few things to throw out here:
-> Still wondering about the Squeakland image; the download is less than 1MB, so obviously it's not in there (right?).
-> When you're developing classes and testing stuff out, do you expose all the instance variables? And then later, remove the accessors you don't want the user to have? I notice that to test/debug it's often easiest to have access to everything from the Workspace, but really don't want that to be exposed to clients of the class.
I frequently write my initial code as if I have accessors but later change it to ivar refs. I think direct variable references are more readable and self accessors are not good for encapsulation.
-> If you were creating a deck (of cards) class and a card class, would you put the card's rank and suit in as strings or as symbols, keeping in mind that you were later going to reveal the class to students for educational purposes? I know I want the deck to be card neutral, i.e., to be usable for a deck of any sort of cards, but the cards themselves (for standard decks), for convenience, are described as being (rank) "King" and (suit) "Hearts". But perhaps that should be #king and #hearts. (I tend to worry about making global symbols: seems like courting trouble.)
I would not use any primitive value type object to represent suit or rank. I would use objects, i.e. a Heart object and a King object. Doing so makes it much easier to do reasoning and comparisons between cards.
I am from the old school and used to start out using symbols, numbers, or strings to represent state. I eventually found out that real objects do a much better job. Rather change my code from some value type of representation to a real object after I found out I need it, I think it is better to just start off that way.
Nothing real urgent, just stuff that has occurred to me.
These were some great answers, guys, thanks. I'll have a lot more the more I write.
I would not use any primitive value type object to represent suit or rank. I would use objects, i.e. a Heart object and a King object. Doing so makes it much easier to do reasoning and comparisons between cards.
I am from the old school and used to start out using symbols, numbers, or strings to represent state. I eventually found out that real objects do a much better job. Rather change my code from some value type of representation to a real object after I found out I need it, I think it is better to just start off that way.
I see the logic of this, but I'm not 100% sure I agree.
The point of having a multiple objects versus a single object would be if the cards behaved differently. But not only do they not behave differently, they only meaning in a larger context. You can't ask the Ace if it's higher or lower than the Jack, for example, because the Ace doesn't know. You can't ask the Ace if it's okay to play itself, because it depends on whether it's Poker, Solitaire, Go Fish, or whatever.
You could say Rules->Deck->Card, because its the rules that determine the relative value of the cards and the composition of the deck. The deck, really, is always going to behave the same. It's just a holder. Its job is to keep track of the cards, shuffle and deal.
Now, if you were making a Magic: The Gathering-type game, yeah, objects for cards--a real hierarchy to boot. And the Deck object should be able to handle that. The rules, however, would determine base play, while deferring to the rule changes specified by the cards.
-----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev- bounces@lists.squeakfoundation.org] On Behalf Of Blake Sent: Saturday, September 10, 2005 4:17 AM To: The general-purpose Squeak developers list Subject: Re: Miscellaneous questions...
These were some great answers, guys, thanks. I'll have a lot more the more I write.
I would not use any primitive value type object to represent suit or rank. I would use objects, i.e. a Heart object and a King object. Doing so makes it much easier to do reasoning and comparisons between cards.
I am from the old school and used to start out using symbols, numbers, or strings to represent state. I eventually found out that real objects do a much better job. Rather change my code from some value type of representation to a real object after I found out I need it, I think it is better to just start off that way.
I see the logic of this, but I'm not 100% sure I agree.
The point of having a multiple objects versus a single object would be if the cards behaved differently. But not only do they not behave differently, they only meaning in a larger context. You can't ask the Ace if it's higher or lower than the Jack, for example, because the Ace doesn't know. You can't ask the Ace if it's okay to play itself, because it depends on whether it's Poker, Solitaire, Go Fish, or whatever.
True, but I think you would find that your game code would be better composed if the representation was a real object. In the simple case the rank object would have a string used to display itself, i.e. Jack, and maybe a rank number used for comparing cards. Obviously, as you point out, the Ace would have to he handled specially. You could also have different rank objects for different games.
But, you will have to come to this realization yourself. It only took me 14 years of ST programming to figure this out. :-) My problem is that I hate adding complexity and to me using objects instead of values increases complexity, so I resisted. But, I have seen too many situations where initially it seemed that a value was simpler and would suffice, but later it turned out not to be the case.
You could say Rules->Deck->Card, because its the rules that determine the relative value of the cards and the composition of the deck. The deck, really, is always going to behave the same. It's just a holder. Its job is to keep track of the cards, shuffle and deal.
Now, if you were making a Magic: The Gathering-type game, yeah, objects for cards--a real hierarchy to boot. And the Deck object should be able to handle that. The rules, however, would determine base play, while deferring to the rule changes specified by the cards.
squeak-dev@lists.squeakfoundation.org