fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fwd: [Fab-user] More Complex Objects in Fabric Variables


From: Paul Baumgart
Subject: Fwd: [Fab-user] More Complex Objects in Fabric Variables
Date: Sat, 21 Mar 2009 13:58:20 -0700

Whoops, forgot to Reply All.

---------- Forwarded message ----------
From: Paul Baumgart <address@hidden>
Date: Sat, Mar 21, 2009 at 1:57 PM
Subject: Re: [Fab-user] More Complex Objects in Fabric Variables
To: Jeff Forcier <address@hidden>


comments inline

On Sat, Mar 21, 2009 at 12:11 PM, Jeff Forcier <address@hidden> wrote:
> On Sat, Mar 21, 2009 at 2:53 PM, Paul Baumgart <address@hidden> wrote:
>> Hi Jeff,
>>
>> I understand it's possible to /assign/ non-strings to Fabric
>> variables, but how do you get them back out as anything other than
>> strings?
>
> Reference config.myvar! This is why I'm confused, you're focusing on
> let(), which may still be around as a vestigal method, but is not how
> you're intended to interface with the ENV as of 0.1.0 -- it's from the
> old let()/set() setup which was in 0.0.9 and earlier.

Ah, ok, I didn't know let() was deprecated. That clears things up, thanks.

>
> Instead, you should probably be doing config.myvar = foo, and then
> e.g. print config.myvar[0] -- and that ought to be 100% Pythonic and
> not do any sort of casting to string (unless you're using the lazy
> string eval, which is only one way of gettng data out of the ENV.)
>
> Let me update your example:
>
>
> def data1():
>   config.data=[1,2,3]
>
> def data2():
>   config.data=[4,5,6]
>
> def show_first_datum():
>   #local('echo $(data[0])') <-- This is not possible right now, but
> might be a legitimate feature request :)
>   config.first_datum=data[0]
>   local('echo $(first_datum)')
>
>
> The result:
>
>
> Fabric v. 0.1.0.
> Running data1...
> Running show_first_datum...
> [localhost] run: echo 1
> 1
> Done.
>
>
> As noted in the example, a potential side-issue here, interpreting
> Python statements such as indexing within the lazily-interpreted
> string, is not currently supported. I personally am not sure it's
> worth using eval() to have that added, either (it's easy enough to use
> normal string interpolation there and do the indexing outside the
> string), but I'll let Christian weigh in before I make any sort of
> judgement :)

Yeah, fair enough. This is plenty functional without eval(); it just
be syntactic sugar, and furthermore I think the error messages would
be fairly cryptic in the case of incorrect syntax within a
lazily-interpreted string, which would probably make it less
user-friendly all-in-all.

>
>
>> (PS: I am using the latest code from the repository, specifically a
>> fork I made on GitHub to play with 2 days ago.)
>
> Yup, but I'm not sure you've read the most recent docs -- they outline
> how to use the 'config' object :)
>
>
> I hope this clears things up some, let me know if I'm still missing something

No, I'm satisfied; thanks for your help. :-)

>
> -Jeff
>
>>
>> Paul
>>
>> On Sat, Mar 21, 2009 at 6:06 AM, Jeff Forcier <address@hidden> wrote:
>>> Hi Paul,
>>>
>>> I'm not sure where you got the impression that Fabric's let/set
>>> functionality only works with strings! It should have always worked
>>> with any Python variable whatsoever. The backend of let/set (which is,
>>> in 0.1.0, just setting/getting attributes of a 'config' object -- may
>>> want to upgrade if you can :)) is just a Python dict, nothing special.
>>>
>>> If you can clarify how that first let() statement you posted "doesn't
>>> work", perhaps we can figure out what went wrong.
>>>
>>> Best,
>>> Jeff
>>>
>>> On Sat, Mar 21, 2009 at 5:29 AM, Paul Baumgart <address@hidden> wrote:
>>>> Hi,
>>>>
>>>> I just recently came across Fabric, and I think it's a really useful
>>>> tool. I was wondering, though, what the best way is to store, for
>>>> example, a list in a Fabric variable.
>>>>
>>>> My use case is as follows:
>>>> I'm creating an Apache virtual host file, and I want to store a list
>>>> of ServerAliases, and then create the file containing these
>>>> ServerAliases dynamically. There are anywhere from 0-5 ServerAliases
>>>> depending on the site, so I want to avoid creating separate variables
>>>> for each "slot". The problem with using a list though, is that, as I
>>>> understand it, it's not possible to do anything with a Fabric variable
>>>> besides cast it to a string, so, for example,
>>>> let(directives="'ServerAlias ' + '\\\\nServerAlias '.join(aliases) +
>>>> '\\\\n'") doesn't work.
>>>>
>>>> As a work-around I added the following functionality:
>>>> http://github.com/paulbaumgart/fabric/blob/e36611d6be5a45b2dbd0771f6698c3c74d81f711/fabric.py#L844
>>>> . Here's the docstring I wrote for it:
>>>> """
>>>> Optionally, you can pass eval=True, and all string values will be 
>>>> interpreted
>>>> as lines of Python code, evaluated over all Fabric variables that have been
>>>> previously set. String interpolation will not be performed if eval=True.
>>>> Be sure to escape backslashes.
>>>>
>>>> Important note: do not reference variables set in the same let command. 
>>>> There
>>>> is no guarantee the variables will be evaluated in the order given.
>>>>
>>>> Given the following fabfile:
>>>> def print_y():
>>>> require('y')
>>>> local('echo "$(y)"');
>>>>
>>>> You can do this:
>>>> $ fab let:x='1',eval=True let:y='x+1',eval=True print_y
>>>> Fabric v. 0.1.1.
>>>> Running let...
>>>> Running let...
>>>> Running print_y...
>>>> [localhost] run: echo "2"
>>>> 2
>>>> Done.
>>>>
>>>> But /not/ this:
>>>> $ fab let:x='1',y='x+1',eval=True print_y > /dev/null
>>>> NameError: name 'x' is not defined
>>>> Make sure the variable exists and that you are not referencing a
>>>> variable defined elsewhere in the same let command.
>>>>
>>>> As you can see, it tries to warn you, but there would have been no error
>>>> message if x had been set previously; it would just have the unexpected
>>>> behavior of using the previous value of x.
>>>> """
>>>>
>>>> But this feels a bit kludgy, especially because the evaluation order
>>>> is not guaranteed for multiple expressions in one let statement.
>>>>
>>>> Can anyone suggest a better way to do this? Did I overlook existing
>>>> functionality that accomplishes the same thing?
>>>>
>>>> Best,
>>>> Paul
>>>>
>>>>
>>>> _______________________________________________
>>>> Fab-user mailing list
>>>> address@hidden
>>>> http://lists.nongnu.org/mailman/listinfo/fab-user
>>>>
>>>
>>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]