标签: metaprogramming

在Ruby中使用yield_method中的yield

是否可以在给定于define_method的块中生成yield关键字?简单的例子:

class Test
  define_method :test do |&b|
    puts b    # => #<Proc:...>
    yield
  end
end

Test.new.test {
  puts "Hi!"
}
Run Code Online (Sandbox Code Playgroud)

此代码在Ruby 1.8.7和1.9.0中都会产生以下错误:

test.rb:4:在`test'中:没有来自test.rb的块(LocalJumpError):8

奇怪的是b块变量!= nilblock_given?返回false.有意的Ruby行为是不是通过Proc对象识别块?

编辑:关于Beerlington的回答:b.call()不是我想要的.块变量仅用于指示实际给出块,并且在define_method中未检测到.

我需要用yield而不是用的原因block.call

我愿意为Ruby中定义新类的方式编写一些扩展,因此当我使用我的扩展时,你可以接受任何可以用纯Ruby编写的代码.

因此,不能考虑类似的语​​义,因为这会强制我的库的用户只使用一种正确的方法来传递一个块.这会破坏TIMTOWTDI规则,并且不会使我的库透明.

真实的例子

以下代码可以简化为上面的代码,因为my_def用途define_method:

require 'my_library'

class Test
  # client can write 'my_def' instead of 'def' since
  # my_library extends Class class
  my_def :test, "some parameter" do
    yield        # …
Run Code Online (Sandbox Code Playgroud)

ruby metaprogramming

29
推荐指数
2
解决办法
5709
查看次数

用于确定类型是否可调用的C++元函数

是否可以编写一个C++(0x)元函数来确定一个类型是否可调用?

通过可调用类型我的意思是函数类型,函数指针类型,函数引用类型(这些被检测到boost::function_types::is_callable_builtin),lambda类型,以及任何具有重载的类operator()(也许任何类具有隐式转换运算符到其中一个,但这不是绝对有必要).

编辑:元函数应检测operator()任何签名的存在,包括模板化operator().我相信这是困难的部分.

编辑:这是一个用例:

template <typename Predicate1, typename Predicate2>
struct and_predicate
{
    template <typename ArgT>
    bool operator()(const ArgT& arg)
    {
        return predicate1(arg) && predicate2(arg);
    }

    Predicate1 predicate1;
    Predicate2 predicate2;
};

template <typename Predicate1, typename Predicate2>
enable_if<ice_and<is_callable<Predicate1>::value,
                  is_callable<Predicate2>::value>::value,
          and_predicate<Predicate1, Predicate2>>::type
operator&&(Predicate1 predicate1, Predicate2 predicate2)
{
    return and_predicate<Predicate1, Predicate2>{predicate1, predicate2};
}
Run Code Online (Sandbox Code Playgroud)

is_callable 是我想要实现的.

c++ metaprogramming c++11

29
推荐指数
3
解决办法
8388
查看次数

28
推荐指数
2
解决办法
9528
查看次数

python类名中的有效字符

我正在动态创建python类,我知道在这种情况下并非所有字符都有效.

在类库中是否有一个方法可以用来清理随机文本字符串,以便我可以将它用作类名?这个或允许的字符列表将是一个很好的帮助.


关于与标识符名称冲突的补充:与@Ignacio一样,在下面的答案中指出,任何有效作为标识符的字符都是类名中的有效字符.你甚至可以毫无困难地使用保留字作为类名.但是有一个问题.如果使用保留字,则无法像其他(非动态创建的)类一样访问类(例如,通过执行globals()[my_class.__name__] = my_class).在这种情况下,保留字始终优先.

python metaprogramming

28
推荐指数
3
解决办法
2万
查看次数

有人可以解释Class.superclass.class.superclass悖论吗?

它可能根本不是一个悖论,但从新手的角度来看,它看起来确实如此.

> Class.superclass
=> Module
> Class.superclass.class
=> Class
> Class.superclass.class.superclass
=> Module
Run Code Online (Sandbox Code Playgroud)

所以类的父级是模块,但模块是一个类?

我怎么能理解这个?

ruby metaprogramming

28
推荐指数
2
解决办法
1万
查看次数

酸洗动态生成的类?

我正在使用type()动态生成最终将被pickle的类.问题是un-pickling进程需要类的定义才能重新构造被pickle的对象.

这就是我被困住的地方.我不知道如何以某种方式 unpickler 提供一种从动态生成的类生成实例的方法.

任何提示赞赏.

谢谢!

这是一个问题的例子:

    >>> class Foo(object):
    ...     pass
    >>> g=type('Goo',(Foo,),{'run':lambda self,x: 2*x } )()
    >>> cPickle.dumps(g)

    PicklingError: Can't pickle <class '__main__.Goo'>: attribute lookup __main__.Goo failed
Run Code Online (Sandbox Code Playgroud)

这显然是有效的,但仅限于从可发现的基类(具有可查找的模块定义)创建的动态类:

import cPickle

class Foo(object): pass

def dynamic(): return type('Goo',(Foo,),{'run':lambda self,x: 2*x } )()

g=type('Goo',(Foo,),{'run':lambda self,x: 2*x , '__reduce__': lambda self: (dynamic,tuple()) } )()

gg=cPickle.loads ( cPickle.dumps(g) )
print gg.run(10)
Run Code Online (Sandbox Code Playgroud)

python metaprogramming class dynamic

28
推荐指数
2
解决办法
4362
查看次数

std :: ratio <>背后的设计原则

我正在研究std::ratio<>C++ 11标准中的类,它允许编译时合理算术.

我发现模板设计和用类实现的操作过于复杂,并且没有找到任何理由为什么他们不能通过实现一个非常简单的理性类并constexpr为操作符定义函数来使用更直接和直观的方法.结果将是一个更容易使用的类,并且编译时优势将保持不变.

有没有人知道当前std::ratio<>设计的优点与使用的简单类实现相比constexpr?实际上,我无法找到当前实现的任何优势.

c++ metaprogramming rational-numbers c++11

28
推荐指数
2
解决办法
4558
查看次数

为什么用enable_if编译错误

为什么这不能用gcc48和clang32编译?

#include <type_traits>

template <int N> 
struct S {

    template<class T> 
    typename std::enable_if<N==1, int>::type
    f(T t) {return 1;};

    template<class T> 
    typename std::enable_if<N!=1, int>::type
    f(T t) {return 2;};
};

int main() {
    S<1> s1;
    return s1.f(99);
}
Run Code Online (Sandbox Code Playgroud)

GCC错误:

/home/lvv/p/sto/test/t.cc:12:2: error: no type named ‘type’ in ‘struct enable_if<false, int>’
  f(T t) {return 2;};
  ^
Run Code Online (Sandbox Code Playgroud)

CLANG错误:

/home/lvv/p/sto/test/t.cc:11:26: error: no type named 'type' in 'std::enable_if<false, int>'; 'enable_if' cannot be used to
      disable this declaration
        typename std::enable_if<N!=1, int>::type
                                ^~~~
/home/lvv/p/sto/test/t.cc:16:7: note: in instantiation of template …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming sfinae enable-if

28
推荐指数
4
解决办法
2万
查看次数

"typename ="在模板参数中的含义是什么?

我在"Effective Modern C++"一书的第189页中看到过这个表达式:

    template<typename T,
             typename = typename std::enable_if<condition>::type>
    explicit Person(T&& n);
Run Code Online (Sandbox Code Playgroud)

我只是想知道" typename =" 这个部分是什么意思.它当然看起来像模板参数的默认参数.但是你不需要typename some_name = ...在默认参数中使用" " 这样的东西吗?第二个模板参数没有名称,我没有看到在这种情况下使用的第二个模板参数.

PS当我在谷歌(或任何其他搜索引擎)上搜索答案时,等号总是被丢弃,这只是让找到答案几乎不可能......

c++ templates metaprogramming generic-programming

28
推荐指数
1
解决办法
2506
查看次数

如何在编译时生成嵌套循环

我有一个整数N,我在编译时知道.我还有一个std :: array,它包含描述N维数组形状的整数.我想在编译时使用元编程技术生成嵌套循环,如下所述.

constexpr int N {4};
constexpr std::array<int, N> shape {{1,3,5,2}};


auto f = [/* accept object which uses coords */] (auto... coords) { 
     // do sth with coords
}; 

// This is what I want to generate.
for(int i = 0; i < shape[0]; i++) {
     for(int j = 0; j < shape[1]; j++) {
          for(int k = 0; k < shape[2]; k++) {
                for(int l = 0; l < shape[3]; l++) …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming c++11 c++14

28
推荐指数
1
解决办法
2290
查看次数