Pregunta

I have a dictionnary defined like this :

  dict set lag_in lagId    1                         
  dict set lag_in m1       port    "1/2"          
  dict set lag_in m1       ixPort  $ix_port(1)    
  dict set lag_in m2       port    "1/20"          
  dict set lag_in m2       ixPort  $ix_port(2)    
  dict set lag_in m3       port    "1/17"          
  dict set lag_in m3       ixPort  $ix_port(17)   
  dict set lag_in itf1     vlan    1
  dict set lag_in itf1     ip      10.0.0.1/24
  dict set lag_in itf1     vlan    20
  dict set lag_in itf1     ip      10.1.1.20/21

I want to define a proc that return a lag member depending on the port or the ixPort. First attempt :

 proc getLagMember { dictionnary args } {  
    set opts(port)      ""
    getopt opts $args

    dict for { key val } $dictionnary {                                          
        if { [regexp {m[1-4]} $key] } {                                          
            if { [dict get $dictionnary $key port] == $opts(port) } {            
                return [dict filter $dictionnary key $key]
            }
        }   
    }   
 }   

But this does not do what I want :

% getLagMember $lag_in -port "1/2"
m1 {port 1/2 ixPort {1 4 1}} ;# I am expecting port 1/2 ixPort {1 4 1}

So I tried to modifiy the return like this :

return [dict filter [dict filter $dictionnary key $key] key $key]

But I still don't have what I want. What am I doing wrong ? And is there a better way to achieve what I want ?

EDIT : Thanks to Glenn I come with this proc, but it does not work with -ixPort option

proc getLagMember { dictionnary args } {
   set opts(port) ""
   set opts(ixPort) ""
   getopt opts $args

   parray opts

   dict for { key val } $dictionnary {                                          
       if {[catch {dict get $val port} port] == 0 && $port eq $opts(port) || [catch {dict get $val ixPort} ixPort] == 0 && $ixPort eq $opts(ixPort)} {
           return $val                                               
       }
   }
}

Output with -port :

% getLagMember $lag_in -port 1/2
opts(ixPort) = 
opts(port)   = 1/1
port 1/1 ixPort {1 4 1}

Output with -ixPort

% getLagMember $lag_in -ixPort {1 4 1}
opts(ixPort) = 1 4 1
opts(port)   = 
ixPort {1 4 1}
¿Fue útil?

Solución

Try

proc getLagMember { dictionnary args } {  
    array set opts {-port ""}
    array set opts $args

    dict for { key val } $dictionnary {                                          
        if {[catch {dict get $val port} port] == 0 && $port eq $opts(-port)} {
            return $val
        }   
    }   
}   

Update: I don't get the same incorrect results you see:

tclsh << 'ENDSCRIPT'
    array set ix_port {1 {1 4 1} 2 2 17 17}
    dict set lag_in lagId    1                         
    dict set lag_in m1       port    "1/2"          
    dict set lag_in m1       ixPort  $ix_port(1)    
    dict set lag_in m2       port    "1/20"          
    dict set lag_in m2       ixPort  $ix_port(2)    
    dict set lag_in m3       port    "1/17"          
    dict set lag_in m3       ixPort  $ix_port(17)   
    dict set lag_in itf1     vlan    1
    dict set lag_in itf1     ip      10.0.0.1/24
    dict set lag_in itf1     vlan    20
    dict set lag_in itf1     ip      10.1.1.20/21

    proc checkAttribute {dict attr} {
        upvar 1 opts opts
        expr {[catch {dict get $dict $attr} value] == 0 && $value eq $opts(-$attr)}
    }

    proc getLagMember { dictionnary args } {  
        array set opts {-port "" -ixPort ""}
        array set opts $args

        dict for { key val } $dictionnary {                                          
            if {[checkAttribute $val port] || [checkAttribute $val ixPort]} {
                return $val
            }   
        }   
    }   

    puts [getLagMember $lag_in -port 1/2]
    puts [getLagMember $lag_in -ixPort {1 4 1}]
ENDSCRIPT
port 1/2 ixPort {1 4 1}
port 1/2 ixPort {1 4 1}

Say, you're not doing this, are you?

getLagMember $lag_in -ixPort 1 4 1
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top