- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
A more generic DelayedInit
Wed, 2011-02-23, 22:48
Hi,
The current definition of the DelayedInit trait has a delayedInit
method defined as:
def delayedInit (x: => Unit) : Unit
Would it be possible to have something a bit more generic? Like
def delayedInit (x: =>Any) : Any
Or even better:
/** the compiler will check that the init block has type T */
trait DelayedInit[T] {
def delayedInit (x: => T) : T
}
I actually have motivating use cases in specs2 for this feature so if
that's easy to do, I'd love to get it.
Thanks,
Eric.
Thu, 2011-02-24, 00:17
#2
Re: A more generic DelayedInit
Sure, actually writing the example shows me that I want something a
slightly different.
In specs2 you can define an Example like this:
"this example must be a success" ! success
If I want to create a "context" with some variables that are setup
with some data for my example I can write:
"this example must be a success" ! context().e1
case class context() {
val data = ...
def e1 = data must beOk
}
It would be nice to be also able to write:
"this example must be a success" ! new context {
data must beOk
}
trait context extends Context {
val data = ...
}
And Context would be a specs2-provided trait such that:
// the init code would be compiler-checked to be a Result
// storing the init code is stored a bit like the impl. in the
Application trait
trait Context extends DelayedInit[Result] {
private var initCode: Option[() => Result] = None
override def delayedInit(body: =>Result) {
initCode = Some(() => body)
}
def result = initCode.getOrElse(success)
}
// then the Context object can be converted to a Resulth implicitly
implicit def contextToResult(c: Context) = c.result
Do you think there are better ways to achieve the behavior I want with
2.8.1?
E.
On Feb 24, 9:03 am, Daniel Sobral wrote:
> Can you provide an example of how you'd use it?
>
>
>
>
>
>
>
>
>
> On Wed, Feb 23, 2011 at 18:48, etorreborre wrote:
> > Hi,
>
> > The current definition of the DelayedInit trait has a delayedInit
> > method defined as:
>
> > def delayedInit (x: => Unit) : Unit
>
> > Would it be possible to have something a bit more generic? Like
>
> > def delayedInit (x: =>Any) : Any
>
> > Or even better:
>
> > /** the compiler will check that the init block has type T */
> > trait DelayedInit[T] {
> > def delayedInit (x: => T) : T
> > }
>
> > I actually have motivating use cases in specs2 for this feature so if
> > that's easy to do, I'd love to get it.
>
> > Thanks,
>
> > Eric.
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
Tue, 2011-03-22, 23:47
#3
Re: A more generic DelayedInit
Hi all,
Before 2.9.0 is out, can I ask again for a little signature change? If
I had at least:
def delayedInit (x: =>Any) : Unit
That would make it possible to "grab" values in the initialization of
an object which would be very helpful for DSLs:
class MySpec extends Specification {
// some examples go here
// they can be captured for later execution
}
If you don't want to go this route, thanks for explaining why it's not
desirable.
Eric.
On Feb 24, 10:15 am, etorreborre wrote:
> Sure, actually writing the example shows me that I want something a
> slightly different.
>
> In specs2 you can define an Example like this:
>
> "this example must be a success" ! success
>
> If I want to create a "context" with some variables that are setup
> with some data for my example I can write:
>
> "this example must be a success" ! context().e1
>
> case class context() {
> val data = ...
> def e1 = data must beOk
> }
>
> It would be nice to be also able to write:
>
> "this example must be a success" ! new context {
> data must beOk
> }
>
> trait context extends Context {
> val data = ...
> }
>
> And Context would be a specs2-provided trait such that:
>
> // the init code would be compiler-checked to be a Result
> // storing the init code is stored a bit like the impl. in the
> Application trait
> trait Context extends DelayedInit[Result] {
> private var initCode: Option[() => Result] = None
> override def delayedInit(body: =>Result) {
> initCode = Some(() => body)
> }
>
> def result = initCode.getOrElse(success)
> }
>
> // then the Context object can be converted to a Resulth implicitly
> implicit def contextToResult(c: Context) = c.result
>
> Do you think there are better ways to achieve the behavior I want with
> 2.8.1?
>
> E.
>
> On Feb 24, 9:03 am, Daniel Sobral wrote:
>
>
>
>
>
>
>
> > Can you provide an example of how you'd use it?
>
> > On Wed, Feb 23, 2011 at 18:48, etorreborre wrote:
> > > Hi,
>
> > > The current definition of the DelayedInit trait has a delayedInit
> > > method defined as:
>
> > > def delayedInit (x: => Unit) : Unit
>
> > > Would it be possible to have something a bit more generic? Like
>
> > > def delayedInit (x: =>Any) : Any
>
> > > Or even better:
>
> > > /** the compiler will check that the init block has type T */
> > > trait DelayedInit[T] {
> > > def delayedInit (x: => T) : T
> > > }
>
> > > I actually have motivating use cases in specs2 for this feature so if
> > > that's easy to do, I'd love to get it.
>
> > > Thanks,
>
> > > Eric.
>
> > --
> > Daniel C. Sobral
>
> > I travel to the future all the time.
Wed, 2011-03-23, 23:47
#4
Re: Re: A more generic DelayedInit
I know of some usecases myself. But it would complicate matters quite a bit. The fundamental problem is that the initialization statements of a class do not form an expression. It's natural to see them as a statement sequence and tack a unit value on at the end. But to see them as an expression that returns a value is quite a shift, semantically.
Cheers
-- Martin
Cheers
-- Martin
Tue, 2011-04-05, 11:37
#5
Re: A more generic DelayedInit
Thinking about your argument again,...
> tack a unit value on at the end. But to see them as an expression that
> returns a value is quite a shift, semantically.
How is that really different from the return value of any definition
('def' I mean)?
A def can be a sequence of statements (with side-effects) where we
return the last expression.
Is there some kind of similar viewpoint that we could adopt here?
E.
On Mar 24, 8:46 am, martin odersky wrote:
> I know of some usecases myself. But it would complicate matters quite a bit.
> The fundamental problem is that the initialization statements of a class do
> not form an expression. It's natural to see them as a statement sequence and
> tack a unit value on at the end. But to see them as an expression that
> returns a value is quite a shift, semantically.
>
> Cheers
>
> -- Martin
Tue, 2011-04-05, 11:47
#6
Re: Re: A more generic DelayedInit
On Tue, Apr 5, 2011 at 12:32 PM, etorreborre <etorreborre@gmail.com> wrote:
Thinking about your argument again,...Yes, but a class initialization is not a def. That's where the essential difference lies.
> tack a unit value on at the end. But to see them as an expression that
> returns a value is quite a shift, semantically.
How is that really different from the return value of any definition
('def' I mean)?
A def can be a sequence of statements (with side-effects) where we
return the last expression.
-- Martin
On Wed, Feb 23, 2011 at 18:48, etorreborre <etorreborre@gmail.com> wrote:
--
Daniel C. Sobral
I travel to the future all the time.