03 Mar, 2009, David Haley wrote in the 21st comment:
Votes: 0
Sounds like implicit methods from Scala.

Personally I like implicits, but clearly you need to use them judiciously. They're nice when you can't change some class for some reason, but also it just doesn't make sense to make a whole new class wrapping it.
03 Mar, 2009, Tyche wrote in the 22nd comment:
Votes: 0
The art of programming is writing good functions.
It's that simple. All the rest is syntactical sugar.
04 Mar, 2009, quixadhal wrote in the 23rd comment:
Votes: 0
Tyche said:
The art of programming is writing good functions.
It's that simple. All the rest is syntactical sugar.


I'll even go a step further and say "good algorithms".

People seemed to get along OK back in the days of BASIC (not Visual Basic… good old line numbered BASIC with GOTO, GOSUB, and the venerable CGOTO), and of course assembly.

Functions are really just a nice way to do a GOSUB without having to use clutzy global variables for parameters, or remember line numbers (or labels) for the entry point.
04 Mar, 2009, David Haley wrote in the 24th comment:
Votes: 0
There becomes a point where ease of expression stops being mere sugar and starts enabling things that would otherwise be far too inconvenient to do yourself. Recursion is an example of this. Oh, sure, yes, you could do everything in machine language, and while you're at it you could enter the code by flipping switches to generate the binary. Yes, the text on top of that is just "sugar" – but it is a layer that, by making things oh-so-much-more convenient, means that people actually do things that they never used to do.

Also, one might wonder about how much code was being written in the days of BASIC, how maintainable it was, and what all it actually did. I shudder to imagine my company's internal development being done in a language like that.
04 Mar, 2009, Tyche wrote in the 25th comment:
Votes: 0
quixadhal said:
Tyche said:
The art of programming is writing good functions.
It's that simple. All the rest is syntactical sugar.


I'll even go a step further and say "good algorithms".

People seemed to get along OK back in the days of BASIC (not Visual Basic… good old line numbered BASIC with GOTO, GOSUB, and the venerable CGOTO), and of course assembly.

Functions are really just a nice way to do a GOSUB without having to use clutzy global variables for parameters, or remember line numbers (or labels) for the entry point.


Perhaps I should have said "good routines", for I didn't mean "function" as a language construct; but rather as an architectural construct as in functional decomposition.
Some old BASICs and other languages did make it somewhat difficult to write and maintain good routines.

A good algorithm is something that does make a routine (or collection of routines), a good routine.
04 Mar, 2009, JohnnyStarr wrote in the 26th comment:
Votes: 0
Yet again, great (though different) points of view.

I think my reasoning goes with David Haley. I am not "trying to avoid" learning OOP. My point is simple. Also i will point out to Vassi that the whole purpose of my post is that the "Bug" function IS NOT a method bound to any class. It does not go to the Player or anything like that, it is in its nature global, because it is needed all throughout the application: it could be used in Commands, Sockets, World Creation, Update Handling, you name it. It is a method that should be used as a 'type' of error handling.

So if your view is that everything should be dealt with per class as an internal method or member. That means that i would have to write a member method called bug in each class?

Player.bug arg
Socket.bug arg
Creation.bug arg

as opposed to

anywhere:

bug arg
04 Mar, 2009, Vassi wrote in the 27th comment:
Votes: 0
Then, again, you'd create your own exception (Which is a class) or if SendBug is simply supposed to log a bug you'd probably have a class that managed the log files and so it would go there. My point was that you seldom have to create a class for 'assorted' funky methods, they still end up getting grouped logically into objects.
04 Mar, 2009, JohnnyStarr wrote in the 28th comment:
Votes: 0
Thanks, i can see that.

I guess my confusion is just based on instance methods vs class methods.
If the goal was to have a collection of Player objects with their own code and methods then certainly, lets not use global handler functions to do that work, keep that inside the player class so that its more manageable and scaleable. But when it comes to something as universal as a bug method, are you saying it would be best to put that into a log / bug class? if so, would it be wise to make an "instance" of that per player? like every player has their own "bug" object? EG:

Player.Bug.SendBug ("something went wrong with the player's command")

Am i making sense?
04 Mar, 2009, Tyche wrote in the 29th comment:
Votes: 0
Sorry, but I have to correct myself.
Tyche said:
There's really no such thing as a global function in Ruby. You are actually defining an instance method on Object, which is then inherited by every class. The context of everything outside a class is "main", which is an instance of Object. You can test this in RocketMud because all these work.
bug "a bug"
Object.bug "a bug"
Mobile.bug "a bug"


Methods defined at the toplevel are by default private instance methods on Object, which is then inherited by every class. The context of everything outside a class is "main", which is an instance of Object. main is "special", the default visibility private.

So the following works everywhere…
bug "a bug" = works

The following will not work…
Object.bug "a bug"
Mobile.bug "a bug"
Object.new.bug "a bug"
Mobile.new.bug "a bug"

Because a private instance method cannot be invoked with a receiver.
Sorry for the confusion. Attempting to verify this using irb reveals different behavior, as defining methods in irb are public.
04 Mar, 2009, David Haley wrote in the 30th comment:
Votes: 0
Well, you were right in some sense that there's no such thing as a global function since global functions are actually methods of a special object. But the distinction doesn't really matter in practice in this case. Maybe it would matter if you're doing something tricky or clever.
04 Mar, 2009, JohnnyStarr wrote in the 31st comment:
Votes: 0
hey guys, i found this on Wiki:

In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. (This concept is also sometimes generalized to restrict the instance to a specific number of objects - for example, we can restrict the number of instances to five objects.) This is useful when exactly one object is needed to coordinate actions across the system.

Would use of the "Singleton" pattern be an OO way of doing what i'm talking about?

PS, Tyche i am aware that your code uses this pattern.
04 Mar, 2009, David Haley wrote in the 32nd comment:
Votes: 0
You're not instantiating anything, so no, you would not use the singleton pattern.
04 Mar, 2009, JohnnyStarr wrote in the 33rd comment:
Votes: 0
Along the same thought process:

For the sake of maintaining code encapsulation / code visibility. I see
the benefit of keeping the players commands within the Player class. But
i would hate to have a huge player.rb file full of commands. So in theory,
could i make a module called "command" that has all the different player commands, within the methods of command refer to instance variables of the player class, and within the Player class "include Command" as a 'mixin' so that i can split up my command files while maintaining direct access to the instance variables?
:grinning:
04 Mar, 2009, David Haley wrote in the 34th comment:
Votes: 0
Yes, you could do that, although I'm not sure why you'd want to. You can implement commands like e.g. Dikurivatives, where the first argument to the command is the person doing the command. Then, you get your data by doing player.get_data_field.

Think about whether you really want the commands to be able to access private fields of the player object. It would be much safer (and better encapsulated) to make commands use the same public interface that everybody uses.
04 Mar, 2009, JohnnyStarr wrote in the 35th comment:
Votes: 0
Hmm, i see. In that sense, i could pass a Player object as a parameter to the global command methods right? EG

cmd.do_go_south(player,arg)

If thats the case, do you see the benefit of keeping the command methods static, or in ruby not instansiating any sort of command object?
04 Mar, 2009, Stormy wrote in the 36th comment:
Votes: 0
staryavsky said:
So in theory, could i make a module called "command" that has all the different player commands, within the methods of command refer to instance variables of the player class, and within the Player class "include Command" as a 'mixin' so that i can split up my command files while maintaining direct access to the instance variables?
:grinning:


Having already read David Haley's response, I think the approach is a matter of preference. I effectively use the approach you're asking about above, which Tyche also used for Teensymud (I'm assuming you saw this?). Commands make sense to me as a behavior of the (we'll say) Mobile class, for example communication or movement.
04 Mar, 2009, David Haley wrote in the 37th comment:
Votes: 0
If you want to treat commands as being modular, you don't want to have to keep mixing in modules (erk, vocabulary overload) into the "Mobile" class. Furthermore, mobiles might have implementation specific fields in them, and you usually don't want external things messing with this internals – it's safer to go through known interfaces. A lot of the brokenness in SMAUG is due to not having well-defined interfaces for this and/or the fact that it's impossible to enforce "private members" in C.

I guess it could be considered preference, but generally I think it's always preferable to encourage safety. "Direct access to the instance variables" is something you should always think twice about – there's a reason why they're hidden/encapsulated in the first place.
04 Mar, 2009, David Haley wrote in the 38th comment:
Votes: 0
Quote
Hmm, i see. In that sense, i could pass a Player object as a parameter to the global command methods right? EG

cmd.do_go_south(player,arg)

That's how I'd probably do it, yes.

Quote
If thats the case, do you see the benefit of keeping the command methods static, or in ruby not instansiating any sort of command object?

I wouldn't instantiate the command object unless it has any kind of state. It might make sense to instantiate an object if for instance the command dynamically constructs a log string based on how arguments are expanded ("fr" –> "Fred").
Basically there's no point having an instance object if there's no instance state.
04 Mar, 2009, Stormy wrote in the 39th comment:
Votes: 0
David Haley said:
If you want to treat commands as being modular, you don't want to have to keep mixing in modules (erk, vocabulary overload) into the "Mobile" class.


I may misunderstand you, but the approach requires only a single mixin.

Quote
Furthermore, mobiles might have implementation specific fields in them, and you usually don't want external things messing with this internals – it's safer to go through known interfaces.


External things couldn't doing any more messing than they could do calling any public method. I mean, if the command includes code to do something harmful, I'm not sure how that's different than any other instance method including code to do something harmful. There's an interface in place too – Mobile#cmd_name(arg).

Quote
I guess it could be considered preference, but generally I think it's always preferable to encourage safety. "Direct access to the instance variables" is something you should always think twice about – there's a reason why they're hidden/encapsulated in the first place.


Kind of the same thing as before…I guess it again falls back to perspective – I see it as a behavior of the class and I'm taking it that you see it as something external somehow gaining access to data it shouldn't have (maybe not?). Like I said though, I don't see the difference between Mobile#save and Mobile#cmd_who(arg). Maybe we're crossing wires.
05 Mar, 2009, David Haley wrote in the 40th comment:
Votes: 0
Stormy said:
I may misunderstand you, but the approach requires only a single mixin.

What if you want plug-in commands? You might not want to dump all commands into a single module. You might want to separate for example core, trusted commands and other commands. Also, you might have commands specific to players, commands specific to non-players, etc.

Stormy said:
External things couldn't doing any more messing than they could do calling any public method. I mean, if the command includes code to do something harmful, I'm not sure how that's different than any other instance method including code to do something harmful. There's an interface in place too – Mobile#cmd_name(arg).

I don't really follow this. The problem isn't that you can call some method that does something – the point is that if you mess with the internals directly, you are more likely to be leaving things in a state inconsistent with what the interface expects.

There's a reason, after all, why you have a public interface over private internals: not only do you not want people to have to deal with understanding the internals, but also, you want to prevent them from screwing them up.

Here's a simple and hopefully very plausible example of why you would prefer using public methods over directly editing private data fields:
Consider a player whose effect list is implemented as a straight array. You later decide that you want it to be an indexed map from effect type to list of effects of that type. Every piece of code manipulating the effect list directly will break. If, instead, people use the proper public interface for adding, removing and iterating over effects, everything still works.
20.0/66