"Andrew Hunt" <andy at toolshed.com> wrote in message news:slrn9ejav8.lma.andy at workbench.toolshed.com... > On Fri, 27 Apr 2001 16:33:05 GMT, Steve Holden <sholden at holdenweb.com> wrote: Hi /\ndy, About an hour or so after your last post to me, I realized you're one of the two authors on the "Programming Ruby" book. Which, of course, was the Ruby book I was telling you I had ;-). ...snip... > > I personally like the style and dynacism of Ruby. For instance, to declare > a class that inherits from another class you simply have: > > class Foo < Bar > def myMethod > File.new ("test.dat", "w") { |f| > f.puts "Hello world!" > } > end > end A SmallScript version could be written as: ========================================= class name=Foo extends=Bar { method { myMethod File('test.dat','w') << 'Hello world!'. } } <!-- Run it here --> {Foo().myMethod} ====== --- OR as single line scripts with just: {File('test.dat','w') << 'Hello world!'} --- OR --- {File('test.dat','w').write('Hello world!')} --- OR --- {File('test.dat','w').puts('Hello world!')} ========================================= The above assumes you have a class <File> with a constructor that takes two arguments (<aFilePath>,<aFilePermissions>) which returns instances that implement the <IStream> interface. The "garbage collector and/or exit" finalization will automatically close the <File> streams left open in the above examples. The same SmallScript compiler will also process this (XML form of Smalltalk) identically: ============================= <class name=Foo extends=Bar> <?method class=Foo [ "<-- specifying class is unnecessary" myMethod (File open: 'test.dat' withPermissions: 'w') nextPutAll: 'Hello world!' ]?> </class> [Foo new myMethod]. --- Which is Equivalent To --- class name=Foo extends=Bar. method class=Foo [ myMethod (File open: 'test.dat' withPermissions: 'w') nextPutAll: 'Hello world!' ]. [Foo new myMethod]. --- [(File open: 'test.dat' withPermissions: 'w') nextPutAll: 'Hello world!'] ============================= But perhaps more interesting is when we want to use module packaging, namespace (scope) binding, and argument typing, as in the following script. NOTE: Without all the numerous explanatory comments, the following code is simple. ==================== module name=MyModule dll=Kernel32 { <!-- Description: Within our module, override any <String> arg calls to <File> #write(<>) or #puts(<>). Note: The subsequent 'module=MyModule' attribute is redundant because it is implied by nesting a method for an external class within our (deployment packaging) module. --> method class=File scope=MyModule module=MyModule { "" ^- Scope limits visibility of this method ::write(<>) "" <- declare an alternate name for this method puts(<String> aString) " ^- limits method binding to types of Strings" /* When we are invoked, log a message to stderr and then invoke the general version. */ "Because we declared that our module act as a namespace for the Kernel32.DLL, via dll=, we can call any of its entry points without needing to declare them." | fileName | := String(MAX_FILE_PATH). fileName.size(GetModuleFileName(null,fileName,fileName.size)). "" Log the message here stderr << '`nWe just used a custom File::write(<>) version'. ' from module: ' << fileName. "" Invoke the standard write routine here return self::File.write(aString) (* We could have qualified the #write message via these other forms: self #File.write(...) self #::File.write(...) *) } <!-- Now execute custom version --> {File('test.dat','w'.puts('Hello world!`n')} <!-- Now execute standard version because of type discrimination --> {File('test.dat','w'.puts(42)} } <!-- Now execute standard version because this eval/immediate method is outside the module scope --> {File('test.dat','w'.puts('`nHello world!')} ==================== I intentionally used a wide variety of the different comment styles allowed (there are additional forms including Unicode variants). The comment forms also enable an extensible form of JavaDoc. Normally, I would adopt one comment style and use it consistently. I should also point out that, in general, the SmallScript parse tree facilities enable an IDE or similar tool to rewrite/transform/present source code into either of the various SmallScript and Smalltalk like styles that were shown in these examples. -- Dave S. > > Here, class Foo inherits from class Bar. Except that class Bar is just an > expression that returns a Class object. In this case it's a constant, but > you could just as easily have: > > class Foo < someMagicRoutine(someArgument, somethingElse) > > File is a real object, we'll call open on it. The opened file object is > passed to the block as local variable f, where we can call puts (named as > in libc) to put a string to the file. At the conclusion of the block, > the file is closed automatically. > > Doesn't look much like Perl to me. Oh, and that's just one way to > use files -- you don't have to use them in a block, but I find it > handy to make sure I've really closed a file :-) > > > /\ndy > > -- > Andrew Hunt, The Pragmatic Programmers, LLC. > Innovative Object-Oriented Software Development > web: http://www.pragmaticprogrammer.com email: andy at pragmaticprogrammer.com > -- > Books by Andrew Hunt and David Thomas: > "The Pragmatic Programmer" (Addison-Wesley 2000) > "Programming Ruby" (Addison-Wesley 2001) > --
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4