|
View:
New views
5 Messages
—
Rating Filter:
Alert me
|
|
|
Private names
by Janne Savukoski
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hello,
This feels a little stupid, and I'm sure there's something fundamentally n00b in this, but anyways... I've been experimenting with this kind of structure (note the pipe, '|', on 2nd line): <clip> 1: sw.sendMessage { 2: new Message | { m => 3: m.setDisplayName(somename) 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) 5: } 6: } </clip> which is similar to 1: val m = new Message 2: m.setDisplayName(somename) 3: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) 4: sw.sendMessage(m) and 1: sw.sendMessage { 2: val m = new Message 3: m.setDisplayName(somename) 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) 5: m 6: } The last one was my favorite before the pipe, but it suffers from the explicit return. The second I don't like a bit as it exposes the name 'm' that is relevant only in the context of the 'sendMessage' invocation. In the first case the pipe—which returns the object itself—replaces an ad-hoc-initialization-block-using-anonymous-subclass. More generally, with pipe I can write a block with a 'private' reference to the context object. (or something...) The pipe is defined simply as implicit def pipe4Any[a](any: a) = new AnyRef { def |(f:a => Unit): a = { f(any); any } } Another nice use case was with logging: 1: rs.report(WARNING, root, format("Resource not found: %s", f.getAbsolutePath) | (warn(_))) where the message "Resource n..." is logged ('warn', shortcut to commons logging) while passed on to the report method. (No ad-hoc-initialization-block-using-anonymous-subclass here.) So, this is just such a trivial use case that I'm sure there's some standard way to do this. Please, feel free to show me the light. :) -janne |
|
|
Re: Private names
by Rafael de F. Ferreira-2
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hi Janne.
I was under the impression that the ad-hoc-initialization-block-using-anonymous-subclass trick was the "standard way" to do this kind of thing in Scala. In your example, I infer that Message is a Java class, but if it was written in Scala, one idiom for initialization would be to declare abstract vals, like this: abstract class Message { val displayName:String val content:String } sw sendMessage (new Message { val displayName = somename val content = format("Hello, %s! %s!", displayName, somecontent) }) Anyway, I really liked your second example, using the pipe and the underscore closure shorthand together looks like a cool technique. On Oct 30, 2007 8:29 AM, Janne Savukoski <janne@...> wrote: > Hello, > > This feels a little stupid, and I'm sure there's something > fundamentally n00b in this, but anyways... I've been experimenting > with this kind of structure (note the pipe, '|', on 2nd line): > > <clip> > 1: sw.sendMessage { > 2: new Message | { m => > 3: m.setDisplayName(somename) > 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > 5: } > 6: } > </clip> > > which is similar to > > 1: val m = new Message > 2: m.setDisplayName(somename) > 3: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > 4: sw.sendMessage(m) > > and > > 1: sw.sendMessage { > 2: val m = new Message > 3: m.setDisplayName(somename) > 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > 5: m > 6: } > > > The last one was my favorite before the pipe, but it suffers from the > explicit return. The second I don't like a bit as it exposes the name > 'm' that is relevant only in the context of the 'sendMessage' > invocation. > > In the first case the pipe—which returns the object itself—replaces an > ad-hoc-initialization-block-using-anonymous-subclass. More generally, > with pipe I can write a block with a 'private' reference to the > context object. (or something...) > > The pipe is defined simply as > > implicit def pipe4Any[a](any: a) = new AnyRef { def |(f:a => Unit): a > = { f(any); any } } > > Another nice use case was with logging: > > 1: rs.report(WARNING, root, format("Resource not found: %s", > f.getAbsolutePath) | (warn(_))) > > where the message "Resource n..." is logged ('warn', shortcut to > commons logging) while passed on to the report method. (No > ad-hoc-initialization-block-using-anonymous-subclass here.) > > So, this is just such a trivial use case that I'm sure there's some > standard way to do this. Please, feel free to show me the light. :) > > > -janne > -- Rafael de F. Ferreira. http://www.rafaelferreira.net/ |
|
|
Re: Private names
by Janne Savukoski
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Hi Rafael!
On 10/30/07, Rafael de F. Ferreira <rafael@...> wrote: > Hi Janne. > > I was under the impression that the > ad-hoc-initialization-block-using-anonymous-subclass trick was the > "standard way" to do this kind of thing in Scala. In your example, I > infer that Message is a Java class, but if it was written in Scala, > one idiom for initialization would be to declare abstract vals, like > this: > > abstract class Message { > val displayName:String > val content:String > } > > sw sendMessage (new Message { > val displayName = somename > val content = format("Hello, %s! %s!", displayName, somecontent) > }) Thanks for confirming that, I had no idea if it was a popular technique with Scala. I myself try to avoid it, as it feels a little intrusive and, well, 'blunt'. :) But it certainly is a smooth way. > Anyway, I really liked your second example, using the pipe and the > underscore closure shorthand together looks like a cool technique. Nice :) . Btw., if the method 'warn' wasn't overloaded, the syntax could be reduced into just '"foo" | warn'. Although, I'm thinking the name '|' may be a little confusing as it doesn't transform the source.. (Instead, if we named map+filter to pipe, it would be shell scripts all over again. :) But anyways, it's funny that there hasn't been more suggestions about some standard ways for replacing this proprietary hack. I'm just a Scala newbie still and I'm sure there's a lot of constructs and syntactic tricks I'm not aware of. -janne > > On Oct 30, 2007 8:29 AM, Janne Savukoski <janne@...> wrote: > > Hello, > > > > This feels a little stupid, and I'm sure there's something > > fundamentally n00b in this, but anyways... I've been experimenting > > with this kind of structure (note the pipe, '|', on 2nd line): > > > > <clip> > > 1: sw.sendMessage { > > 2: new Message | { m => > > 3: m.setDisplayName(somename) > > 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > > 5: } > > 6: } > > </clip> > > > > which is similar to > > > > 1: val m = new Message > > 2: m.setDisplayName(somename) > > 3: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > > 4: sw.sendMessage(m) > > > > and > > > > 1: sw.sendMessage { > > 2: val m = new Message > > 3: m.setDisplayName(somename) > > 4: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) > > 5: m > > 6: } > > > > > > The last one was my favorite before the pipe, but it suffers from the > > explicit return. The second I don't like a bit as it exposes the name > > 'm' that is relevant only in the context of the 'sendMessage' > > invocation. > > > > In the first case the pipe—which returns the object itself—replaces an > > ad-hoc-initialization-block-using-anonymous-subclass. More generally, > > with pipe I can write a block with a 'private' reference to the > > context object. (or something...) > > > > The pipe is defined simply as > > > > implicit def pipe4Any[a](any: a) = new AnyRef { def |(f:a => Unit): a > > = { f(any); any } } > > > > Another nice use case was with logging: > > > > 1: rs.report(WARNING, root, format("Resource not found: %s", > > f.getAbsolutePath) | (warn(_))) > > > > where the message "Resource n..." is logged ('warn', shortcut to > > commons logging) while passed on to the report method. (No > > ad-hoc-initialization-block-using-anonymous-subclass here.) > > > > So, this is just such a trivial use case that I'm sure there's some > > standard way to do this. Please, feel free to show me the light. :) > > > > > > -janne > > > > > > -- > Rafael de F. Ferreira. > http://www.rafaelferreira.net/ > -- Janne Savukoski Internet programmer email/im: janne@... mobile: +358 (40) 568 4246 blog: http://zimboe.wordpress.com/ |
|
|
Re: Private names
by Robin Message
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Okay, I'm only getting started with Scala, but how about:
1: sw.sendMessage { m => 2: m.setDisplayName(somename) 3: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) 4: } With sendMessage defined as: def sendMessage(setter:Message=>unit) { var msg=new Message() setter(msg) //..do something with msg } If you want to send subclasses of message, then the code ought to look like: 1: sw.sendMessage[SubMessage] { m => 2: m.setDisplayName(somename) 3: m.setContent(format("Hello, %s! %s!", displayName, somecontent)) 4: } With sendMessage defined as: def sendMessage[T <: Message](setter:T=>unit) { var msg=new T() setter(msg) //..do something with msg } Alas, that doesn't compile. Any guru want o suggest how that could/should be done? Cheers, Robin Message On Wed, 2007-10-31 at 17:29 +0200, Janne Savukoski wrote: > Hi Rafael! > > On 10/30/07, Rafael de F. Ferreira <rafael@...> wrote: > > Hi Janne. > > > > I was under the impression that the > > ad-hoc-initialization-block-using-anonymous-subclass trick was the > > "standard way" to do this kind of thing in Scala. In your example, I > > infer that Message is a Java class, but if it was written in Scala, > > one idiom for initialization would be to declare abstract vals, like > > this: > > > > abstract class Message { > > val displayName:String > > val content:String > > } > > > > sw sendMessage (new Message { > > val displayName = somename > > val content = format("Hello, %s! %s!", displayName, somecontent) > > }) > > Thanks for confirming that, I had no idea if it was a popular > technique with Scala. I myself try to avoid it, as it feels a little > intrusive and, well, 'blunt'. :) But it certainly is a smooth way. > > > > Anyway, I really liked your second example, using the pipe and the > > underscore closure shorthand together looks like a cool technique. > > Nice :) . Btw., if the method 'warn' wasn't overloaded, the syntax > could be reduced into just '"foo" | warn'. Although, I'm thinking the > name '|' may be a little confusing as it doesn't transform the > source.. (Instead, if we named map+filter to pipe, it would be shell > scripts all over again. :) > > But anyways, it's funny that there hasn't been more suggestions about > some standard ways for replacing this proprietary hack. I'm just a > Scala newbie still and I'm sure there's a lot of constructs and > syntactic tricks I'm not aware of. > > -janne |
|
|
Re: Private names
by Robin Message
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message I've found a solution using one factory object per Message subtype.
abstract class MessageFactory[M] { def make(): M } class Message{ var name:String="" def setName(newname:String) {name=newname} def send()=println(name) } implicit object MessageMessageFactory extends MessageFactory[Message] { def make()=new Message() } class SubMessage extends Message { var t:String="" def setType(newtype:String) {t=newtype} override def send()=println(name+" ("+t+")") } implicit object SubMessageMessageFactory extends MessageFactory[SubMessage] { def make()=new SubMessage() } def sendMessage[T <: Message](setter:T=>unit)(implicit factory: MessageFactory[T]) { var msg:T=factory.make() setter(msg) msg.send() } sendMessage[Message] { m => m.setName("foo") m.setName("bar") } sendMessage[SubMessage] { m => m.setType("count") m.setName("Update") } I'd say you couldn't do it with less syntax, it's safe and it's very readable. However, each message needs a factory method attaching to it which is a little annoying, but very workable. What do you think? Also, a note to Scala writers - would it be possible to compile "new T()", where T is a type variable, into a factory method like I've done here? One other thing: The technique you described below is not very safe, since if you mistype the name of one of the parameters, the compiler will give no error, but your code will not work (suppose you wrote "val displaYYYName = somename", displayName will still equal null) Robin > > > I was under the impression that the > > > ad-hoc-initialization-block-using-anonymous-subclass trick was the > > > "standard way" to do this kind of thing in Scala. In your example, I > > > infer that Message is a Java class, but if it was written in Scala, > > > one idiom for initialization would be to declare abstract vals, like > > > this: > > > > > > abstract class Message { > > > val displayName:String > > > val content:String > > > } > > > > > > sw sendMessage (new Message { > > > val displayName = somename > > > val content = format("Hello, %s! %s!", displayName, somecontent) > > > }) > > > > Thanks for confirming that, I had no idea if it was a popular > > technique with Scala. I myself try to avoid it, as it feels a little > > intrusive and, well, 'blunt'. :) But it certainly is a smooth way. > > > > > > > Anyway, I really liked your second example, using the pipe and the > > > underscore closure shorthand together looks like a cool technique. > > > > Nice :) . Btw., if the method 'warn' wasn't overloaded, the syntax > > could be reduced into just '"foo" | warn'. Although, I'm thinking the > > name '|' may be a little confusing as it doesn't transform the > > source.. (Instead, if we named map+filter to pipe, it would be shell > > scripts all over again. :) > > > > But anyways, it's funny that there hasn't been more suggestions about > > some standard ways for replacing this proprietary hack. I'm just a > > Scala newbie still and I'm sure there's a lot of constructs and > > syntactic tricks I'm not aware of. |
| Free embeddable forum powered by Nabble | Forum Help |