Jump to page: 1 2
Thread overview
Neat trick - 'with' and unnamed objects + 'with' proposals
Apr 24, 2007
Bill Baxter
Apr 24, 2007
Denis Golovan
Apr 24, 2007
Bill Baxter
Apr 24, 2007
Max Samukha
Apr 24, 2007
eao197
Apr 24, 2007
BCS
Apr 24, 2007
Bill Baxter
Apr 24, 2007
BCS
Apr 24, 2007
Bill Baxter
Apr 24, 2007
Max Samukha
Apr 24, 2007
Max Samukha
Apr 24, 2007
Bill Baxter
Apr 24, 2007
Max Samukha
Apr 24, 2007
Bill Baxter
Apr 24, 2007
Max Samukha
Apr 24, 2007
Dan
Apr 24, 2007
BCS
April 24, 2007
I just discovered this little trick that I think is way cool.
You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable.


with(new someGUIWidget(myParent)) {
   shown = true;
   focusable = false;
}

That's really nifty for GUI code.

This could be even more useful if there were some kind of 'this' for 'with' blocks.  Then you could also call non-member functions.

with(new someGUIWidget(myParent)) {
   shown = true;
   focusable = false;
   some_global_function(this);
}

Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:

with(new someGUIWidget(myParent)) {
   some_global_function(with);
}

And even cooler would be if you could have a 'with-expression' that just evaluates to the thing in the parens:

auto obj = with(new someGUIWidget(myParent))
{
   shown = true;
   focusable = false;
   some_global_function(this);
};


Sometimes I've seen people try to make APIs in C++ where all the attribute setters return the object so that property setting can be chained, like:

     myObject.set_focusable(true).set_shown(true);

Presumably the objective is to avoid repeating the name of the object a lot.  But that never works out too well, because making every mutator return a pointer to 'this' is just not so practical in the end, and forcing every property setting operation to use function call syntax is also not so great.

--bb
April 24, 2007
> Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:

  +1. That feature is useful sometimes.

> --bb


April 24, 2007
Denis Golovan wrote:
>> Or perhaps analogous to how constructors are called 'this()' and have a
>> 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:
> 
>   +1. That feature is useful sometimes.

You say "is" as if it exists in some other language that you've used? Does it? And if so what's the syntax?

--bb
April 24, 2007
On Tue, 24 Apr 2007 22:03:07 +0900, Bill Baxter <dnewsgroup@billbaxter.com> wrote:

>Denis Golovan wrote:
>>> Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:
>> 
>>   +1. That feature is useful sometimes.
>
>You say "is" as if it exists in some other language that you've used? Does it? And if so what's the syntax?
>
>--bb
Object initializers in C# 3.0 seem to do a similar thing but they
don't provide a way to call global (and local, I guess) functions with
'this'.
http://community.bartdesmet.net/blogs/bart/archive/2006/12/04/C_2300_-3.0-Feature-Focus-_2D00_-Part-2-_2D00_-Object-Initializers.aspx
April 24, 2007
On Tue, 24 Apr 2007 17:03:07 +0400, Bill Baxter <dnewsgroup@billbaxter.com> wrote:

> Denis Golovan wrote:
>>> Or perhaps analogous to how constructors are called 'this()' and have a
>>> 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:
>>    +1. That feature is useful sometimes.
>
> You say "is" as if it exists in some other language that you've used? Does it? And if so what's the syntax?

Such behaviour can easily be implemented in Ruby. This is very simple demonstration:

  # Just a demo class.
  class Demo
    attr_reader :shown
    attr_reader :focused
  end

  # Yet another demo class.
  class AnotherDemo
    attr_reader :title
  end

  # A globe function to be called with 'with' keyword.
  def some_global_function( obj )
    p obj
  end

  # This is implementation of 'with'.
  def with( obj, &blk )
    # 1: introduce a new method 'with' into object 'obj'.
    class <<obj
      def with; self; end
    end

    # 2: run the specified block on 'obj' context.
    # Because now 'obj' has method 'with' it can be
    # called from block body.
    begin
      obj.instance_eval &blk
    ensure
      # 3: method 'with' no more needed.
      class <<obj
        remove_method( :with )
      end
    end

    obj
  end

  # This is usage of 'with'
  d = with( Demo.new ) {
    @shown = false
    @focused = true
    # Content of new object of class Demo must be shown here.
    some_global_function( with )
  }
  a = with( AnotherDemo.new ) {
    @title = 'Hello, World'
    # Content of new object of class AnotherDemo must be shown here.
    some_global_function( with )
  }

  # Simple debug output.
  puts "d: shown: #{d.shown}, focused: #{d.focused}"
  puts "a: title: #{a.title}"

That program prints:

#<Demo:0x2c7d448 @shown=false, @focused=true>
#<AnotherDemo:0x2c7d3f8 @title="Hello, World">
d: shown: false, focused: true
a: title: Hello, World

Such implementation of 'with' assumes that obj hasn't method 'with'. But this limitation can be removed via aliasing.

-- 
Regards,
Yauheni Akhotnikau
April 24, 2007
Bill Baxter wrote:
> I just discovered this little trick that I think is way cool.
> You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable.
> 
> 
> with(new someGUIWidget(myParent)) {
>    shown = true;
>    focusable = false;
> }
> 
> That's really nifty for GUI code.
> 
> This could be even more useful if there were some kind of 'this' for 'with' blocks.  Then you could also call non-member functions.
> 
> with(new someGUIWidget(myParent)) {
>    shown = true;
>    focusable = false;
>    some_global_function(this);
> }
> 
> Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:
> 
> with(new someGUIWidget(myParent)) {
>    some_global_function(with);
> }
> 
> And even cooler would be if you could have a 'with-expression' that just evaluates to the thing in the parens:
> 
> auto obj = with(new someGUIWidget(myParent))
> {
>    shown = true;
>    focusable = false;
>    some_global_function(this);
> };
> 
> 
> Sometimes I've seen people try to make APIs in C++ where all the attribute setters return the object so that property setting can be chained, like:
> 
>      myObject.set_focusable(true).set_shown(true);
> 
> Presumably the objective is to avoid repeating the name of the object a lot.  But that never works out too well, because making every mutator return a pointer to 'this' is just not so practical in the end, and forcing every property setting operation to use function call syntax is also not so great.
> 
> --bb


how about take a trick from "if"

with(auto name = new someGUIWidget(myParent))
{
   shown = true;
   focusable = false;
   some_global_function(name);
}
April 24, 2007
BCS wrote:
> Bill Baxter wrote:

> how about take a trick from "if"
> 
> with(auto name = new someGUIWidget(myParent))
> {
>    shown = true;
>    focusable = false;
>    some_global_function(name);
> }

Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work.  :-(

Looking at the spec it seems that's special to 'if'.   It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added.

--bb
April 24, 2007
Bill Baxter wrote:
> BCS wrote:
> 
>> Bill Baxter wrote:
> 
> 
>> how about take a trick from "if"
>>
>> with(auto name = new someGUIWidget(myParent))
>> {
>>    shown = true;
>>    focusable = false;
>>    some_global_function(name);
>> }
> 
> 
> Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work.  :-(
> 
> Looking at the spec it seems that's special to 'if'.   It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added.
> 
> --bb

Ohhh. That would be nice in switch ... and while...
April 24, 2007
BCS wrote:
> Bill Baxter wrote:
>> BCS wrote:
>>
>>> Bill Baxter wrote:
>>
>>
>>> how about take a trick from "if"
>>>
>>> with(auto name = new someGUIWidget(myParent))
>>> {
>>>    shown = true;
>>>    focusable = false;
>>>    some_global_function(name);
>>> }
>>
>>
>> Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work.  :-(
>>
>> Looking at the spec it seems that's special to 'if'.   It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added.
>>
>> --bb
> 
> Ohhh. That would be nice in switch ... and while...

I was thinking 'while' would have issues, because the condition is evaluated multiple times.  So I left it off the list.  Maybe it's not a problem though.  Just make it equiv to
{
   typeof(condition()) x;
   while(x = condition()) {
       // do stuff
   }
}

--bb
April 24, 2007
On Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup@billbaxter.com> wrote:

>BCS wrote:
>> Bill Baxter wrote:
>>> BCS wrote:
>>>
>>>> Bill Baxter wrote:
>>>
>>>
>>>> how about take a trick from "if"
>>>>
>>>> with(auto name = new someGUIWidget(myParent))
>>>> {
>>>>    shown = true;
>>>>    focusable = false;
>>>>    some_global_function(name);
>>>> }
>>>
>>>
>>> Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work.  :-(
>>>
>>> Looking at the spec it seems that's special to 'if'.   It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added.
>>>
>>> --bb
>> 
>> Ohhh. That would be nice in switch ... and while...
>
>I was thinking 'while' would have issues, because the condition is
>evaluated multiple times.  So I left it off the list.  Maybe it's not a
>problem though.  Just make it equiv to
>{
>    typeof(condition()) x;
>    while(x = condition()) {
>        // do stuff
>    }
>}
>
>--bb

This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.



« First   ‹ Prev
1 2